В C++ оператор switch выражение гарантии оценки



относительно переключателя стандартные состояния следующие. " когда оператор switch выполняется, его состояние оценивается и сравнивается с каждой константой case."



означает ли это, что выражение условия вычисляется один раз и только один раз, и оно гарантируется стандартом для каждого компилятора?



например, когда функция используется в головке оператора switch, с побочным эффектом.



int f() { ... }
switch (f())
{
case ...;
case ...;
}
511   6  

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

    Ничего не найдено.