почему std :: cin не может вызвать исключение, когда я прямо говорю ему это сделать? [Дубликат]

Тип математики с плавающей запятой, которая может быть реализована на цифровом компьютере, обязательно использует приближение реальных чисел и операций над ними. (Стандартная версия стандартная работает до более чем пятидесяти страниц документации и имеет комитет для рассмотрения ее ошибок и дальнейшего уточнения.)

Это приближение представляет собой смесь приближений разного типа, каждый из которых можно либо игнорировать, либо тщательно учитывать из-за его конкретного способа отклонения от точности. Это также включает в себя ряд явных исключительных случаев как на уровне аппаратного обеспечения, так и на уровне программного обеспечения, которое большинство людей прогуливает прямо мимо, делая вид, что не замечает.

Если вам нужна бесконечная точность (например, вместо числа π одного из его более коротких резервных копий), вы должны написать или использовать символическую математическую программу.

Но если вы в порядке с идеей о том, что иногда математика с плавающей запятой нечеткая по значению и логике и ошибки могут быстро накапливаться, и вы можете написать свои требования и тесты для этого, тогда ваш код может часто проходить с помощью того, что находится в вашем FPU.

3
задан Superlokkus 3 February 2016 в 16:52
поделиться

2 ответа

Кажется, что libc ++ следует этому требованию:

Каждая форматированная входная функция начинает выполнение, создавая объект класса sentry с noskipws (вторым) аргументом false. Если часовой объект возвращает true, при преобразовании в значение типа bool, эта функция пытается получить запрошенный вход. Если во время ввода выбрано исключение, тогда ios::badbit включается312 в состоянии ошибки *this. Если (exceptions()&badbit) != 0, то исключение будет восстановлено. В любом случае отформатированная функция ввода уничтожает объект часовой. Если исключение не было выбрано, оно возвращает *this.

312) Это выполняется, не вызывая выброса ios::failure.

(цитируется по N4567 § 27.7.2.2.1 [istream.formatted.reqmts], но C ++ IS содержит идентичную формулировку. Акцент мой)

Я не знаю, действительно ли это означает «если (exceptions()&badbit) == 0, то входная функция должна но не исключение »

7
ответ дан cpplearner 23 August 2018 в 17:26
поделиться

Сначала вы получите некоторую справочную информацию (каждый из них объясняется ниже в соответствующем заголовке, если вы хотите получить дополнительную информацию):

  • Стандарт требует, чтобы istream s восстанавливал только / g10], когда ios_base::badbit установлен в basic_istream::exceptions
  • libstdc ++ не соответствует этому требованию, но libc ++ делает
  • libc ++ делает недействительными ошибки, запрашивающие его зеркалирование поведения libstdc ++
  • libc ++ proffers ios_base::badbit побито с нужным ios_base::iostate в качестве обходного пути

К сожалению, это обходное решение имеет побочный эффект также ретронирования всякий раз, когда ios_base::badbit устанавливается независимо от ios_base::failbit: http://en.cppreference.com/w/cpp/io/ios_base/iostate#The_badbit

Если вы ищете бросок, чтобы произойти только , когда ios_base::failbit установлен, и вам нужно, чтобы это было одинаковое поведение в libc ++ и libstdc ++, вам нужно будет проверить ios_base::badbit после каждой операции ввода, происходящей на istream. Это должно выглядеть примерно так:

if((is.rdstate() & ios_base::failbit) != 0) throw ios_base::failure("basic_ios::clear");

Как отмечено cpplearner , вы даже не можете использовать basic_istream::fail , у вас есть чтобы выполнить бит-тест теста istream rdstate . Но, честно говоря, это лишь добавляет немного сложности.

Что может сделать это монументальной задачей, так это то, в какой степени используется istream. Широкое использование функции istream можно было бы устранить с помощью вспомогательных функций, но использование istream_iterator s или сложных перегрузок оператора извлечения быстро сделает ручную проверку этой необоснованной задачи.

Если вы окажетесь там я бы серьезно рассмотрел возможность обходного пути is.exceptions(ios_base::failbit | ios_base::badbit).


Стандарт требует, чтобы istream s реконструировал только , когда ios_base::badbit установлен в basic_istream::exceptions ]

Вызов basic_istream::exceptions(istream::failbit) установит маску, которую можно получить, вызвав basic_istream::exceptions(), которая согласно 27.5.5.4 [iosstate.flags] / 11 стандарта:

Маска, которая определяет, какие элементы, установленные в rdstate(), вызывают исключения.

Это поддерживается в 27.7.2.2.3 [istream :: extractors] / 15 для неотформатированных методы вставки:

Если он не вставил никаких символов, потому что он поймал исключение, вызванное при извлечении символов из *this и failbit включено в exceptions() (27.5.5.4), тогда пойманное исключение отменяется.

Однако для форматированного ввода это retrograded в 27.7.2.2.1 [istream.formatted.reqmts] / 1; требуя, чтобы бросок произошел только тогда, когда бит и маска и ios_base::badbit отличны от нуля:

Если во время ввода выбрано исключение, то ios::badbit включается в *this. Если (exceptions()&badbit) != 0, то исключение будет восстановлено.


libstdc ++ не соответствует этому требованию, но libc ++ делает

ios_base::failbit должен быть установлен на нем соответствующий istream для таких событий, как:

Числовые, указательные и логические входные перегрузки basic_istream::operator>> (технически, перегрузки num_get::get, которые они вызывают), если вход не может быть анализируется как допустимое значение или если синтаксический анализ не подходит для целевого типа.

[ Источник ]

Если используется только ios_base::failbit установлен на маске basic_istream::exceptions ', и происходит событие, в результате чего устанавливается ios_base::failbit, например, извлечение недопустимого числа, как описано выше:


libc ++ делает недействительными ошибки, запрашивающие зеркалирование поведения libstdc ++

Теперь теперь недействителен ошибка для libc ++ для этой самой проблемы. Цитирование 27.7.2.1 [istream] / 4

Если одна из этих вызываемых функций выдает исключение, то, если явно не указано иначе, входная функция устанавливает badbit в состояние ошибки. Если функция badbit включена в exceptions(), функция ввода отменяет исключение, не выполняя его действия, в противном случае он ничего не бросает и продолжает действовать так, как если бы вызванная функция вернула индикацию отказа.

< hr>

libc ++ proffers ios_base::badbit побито с нужным ios_base::iostate в качестве обходного пути

Наш собственный Говард Хиннант (который также является представителем libc ++, который invalidated связанная ошибка libc ++) предлагает в ответ на дубликат этого вопроса (а также в ошибке libc ++), что вы используете обходной путь:

is.exceptions(ios_base::failbit | ios_base::badbit);
7
ответ дан cpplearner 23 August 2018 в 17:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: