В C++ оператор switch выражение гарантии оценки
относительно переключателя стандартные состояния следующие. " когда оператор switch выполняется, его состояние оценивается и сравнивается с каждой константой case."
означает ли это, что выражение условия вычисляется один раз и только один раз, и оно гарантируется стандартом для каждого компилятора?
например, когда функция используется в головке оператора switch, с побочным эффектом.
int f() { ... }
switch (f())
{
case ...;
case ...;
}
6 ответов:
Я думаю, что это гарантировано, что
fвызывается только один раз.сначала у нас есть
условие должно быть интегрального типа, типа перечисления или типа класса.
[6.4.2 (1)] (нецелой материал здесь не применяется), и
значение условия, которое является выражением, является значением выражение
[6.4 (4)]. Кроме того,
в значение условия будет называться просто "условие", где использование однозначно.
[6.4 (4)] это означает, что в нашем случае "условие" - это просто простое значение типа
int, а неf.fиспользуется только для поиска значения для условия. Теперь, когда контроль достигаетswitchсообщенииего состояние оценивается
[6.4.2 (5)], т. е. мы используем значение
intчто возвращается наfкак наши "условия". Наконец, условие (которое является значением типаint, а неf), isпо сравнению с каждым из константных
[6.4.2 (5)]. Это не вызовет побочных эффектов от
fснова.все цитаты из N3797. (Также проверено N4140, без разницы)
чтение N4296
Страница 10 пункт 14:
каждое вычисление значения и побочный эффект, связанный с полным выражением, упорядочиваются перед каждым значением расчет и побочный эффект, связанный со следующего полного выражения.
когда я прочитал первую строку параграфа. 10 (выше):
полное выражение-это выражение, которое не является суб-выражением другой выражение.
Я должен верить, что условие
switchоператор является полным выражением, и каждое выражение условия является полным выражением (хотя и тривиальным при выполнении).A
switch- Это утверждение, а не выражение (см. 6.4.2 и многие другие места).так что, читая оценку
switchдолжно состояться до оценкиcaseконстанты.как всегда многие пункты сводятся к извилистому чтению спецификации прийти к очевидному выводу.
если бы я рассмотрел это предложение, я бы предложил следующую поправку (в полужирный):
когда оператор switch выполняется, его состояние оценивается один раз за выполнение оператора switch и по сравнению с каждым из константных.
да выражение вычисляется только один раз при выполнении оператора switch:
§ 6.4 инструкции по выбору
4 [...] Значение условия, которое является выражением, является значением выражение.[ ..] Значение условия будет называться просто "условие", где использование является однозначным.
Это означает, что выражение вычисляется, и его значение считается
conditionбудет оценивается по каждомуcaseзаявление.
6.4.4:
...Значение условия, которое является выражением, является значением выражения, контекстуально преобразуется в bool для заявления, за исключением переключатель.;..Значение условия будет называться просто "условие", где использование однозначно
в моем понимании, приведенная выше цитата эквивалентна следующему псевдокоду:
switchCondition := evaluate(expression)теперь добавьте свою цитату
...его состояние оценивается и сравнивается с каждой константой случая.
который должен быть переведен на:
foreach case in cases if case.constant == switchCondition goto case.blockТак что да, похоже, что это так.
этот код печатает
helloодин или два раза?int main() { printf("hello\n"); }Ну, я думаю, что ответ заключается в более общем понимании того, что описывает стандарт, а не в конкретном
switchзаявление редакции.по состоянию на выполнение программы [вступление.казнь] стандарт описывает поведение некоторых абстрактной машины это выполняет программа разбирается по C++ грамматика. Это не действительно определите, что означает "абстрактная машина" или "выполняет", но предполагается, что они означают их очевидные концепции информатики, т. е. компьютер, который проходит через абстрактное синтаксическое дерево и оценивает каждую его часть в соответствии с семантикой, описанной стандартом. Это означает, что если вы написали что-то один раз, то когда исполнение доходит до этой точки, она вычисляется только один раз.
более актуальным вопросом является "когда реализация может оценить что-то не так написано в программе"? Для этого существует правило as-if и куча неопределенных поведений, которые позволяют реализации отклоняться от этой абстрактной интерпретации.
гарантируется выражение, которое вычисляется только один раз потоком управления. Это оправдано в стандарте N4431 §6.4.2 / 6 оператор switch [stmt.переключатель] (выделено мной):
метки case и default сами по себе не изменяют поток контроль, который продолжается беспрепятственно через такие метки. для выхода из выключатель сломать, 6.6.1. [ Примечание: обычно, субстанция, которая является предметом переключатель является составным, и появляются метки case и default о высказываниях верхнего уровня, содержащихся в составе (соединение) субстанция, но это не обязательно. Объявления могут появляться в подстановка переключателя-утверждение. - конец Примечание ]
Comments