Подтвердить что ты не робот

Операционная система

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

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

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

int f() { ... }
switch (f())
{
    case ...;
    case ...;
}
4b9b3361

Ответ 1

Я думаю, что гарантировано, что f вызывается только один раз.

Сначала мы имеем

Условие должно быть целым типом, типом перечисления или типом класса.

[6.4.2 (1)] (здесь не применяется неотмеченный материал) и

Значение условия, являющегося выражением, является значением Выражение

[6.4 (4)]. Кроме того,

Значение условия будет называться просто "условием", в котором использование недвусмысленно.

[6.4 (4)] Это означает, что в нашем случае "условие" является просто равным значением типа int, а не f. f используется только для определения значения условия. Теперь, когда управление достигает инструкции switch

его условие оценивается

[6.4.2 (5)], т.е. мы используем значение int, которое возвращается f как наше "условие". Тогда, наконец, условие (которое является значением типа int, а не f), равно

по сравнению с каждой константой случая

[6.4.2 (5)]. Это не вызовет побочные эффекты от f снова.

Все цитаты из N3797. (Также проверено N4140, нет разницы)

Ответ 2

Чтение N4296

Page 10 para 14:

Каждое вычисление значения и побочный эффект, связанные с полным выражением, секвенируются перед каждым значением вычисление и побочный эффект, связанные со следующим полным выражением, которое должно быть оценено.

Когда я прочитал первую строку параграфа. 10 (выше этого):

Полное выражение - это выражение, которое не является подвыражением другое выражение.

Я должен полагать, что условие оператора switch является полным выражением, а каждое выражение условия является полным выражением (хотя и тривиальным при выполнении).

A switch - это выражение, а не выражение (см. 6.4.2 и многие другие места).

Таким образом, при этом чтении оценка switch должна выполняться перед оценкой констант case.

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

Если я рассмотрю это предложение, я бы предложил следующую поправку (в жирный):

Когда оператор switch выполняется, его состояние оценивается один раз за выполнение оператора switch и сравнивается с каждой константой случая.

Ответ 3

Да выражение оценивается только один раз, когда выполняется оператор switch:

§ 6.4 Операции выбора

4 [...] Значение условия, являющегося выражением, является значением выражение [...] Значение условия будет называться просто "условием", где использование недвусмысленно.

Это означает, что выражение оценивается, и его значение считается condition, которое должно быть оценено против каждого оператора case.

Ответ 4

Раздел 6.4.4:

... Значение условия, являющегося выражением, является значением выражение, контекстно преобразованное в bool для операторов, отличных от switch;... Значение условия будет называться просто "условием", в котором использование недвусмысленно

В моем понимании приведенная выше цитата эквивалентна следующему псевдокоду:

switchCondition := evaluate(expression)

Теперь добавьте свою цитату

... его состояние оценивается и сравнивается с каждой константой случая.

Который должен быть переведен на:

foreach case in cases
    if case.constant == switchCondition
         goto case.block

Так что да, похоже, это так.

Ответ 5

Этот код печатает hello один или два раза?

int main() {
    printf("hello\n");
}

Хорошо, я думаю, что ответ заключается в более общем понимании того, что описывает стандарт, а не в конкретной формулировке формулировки switch.

В соответствии с Исполнением программы [intro.execution] стандарт описывает поведение какой-либо абстрактной машины, которая выполняет программу, анализированную по грамматике С++. Он не определяет, что означает "абстрактная машина" или "выполняет", но предполагается, что они означают их очевидные концепции компьютерной науки, то есть компьютер, который проходит через абстрактное синтаксическое дерево и оценивает каждую его часть в соответствии с семантикой, описанной в стандарт. Это означает, что если вы что-то написали один раз, то, когда выполнение дойдет до этой точки, оно оценивается только один раз.

Более актуальным вопросом является "когда реализация может оценивать что-то не так, как написано в программе"? Для этого существует правило as-if и куча поведения undefined, которые позволяют реализации отклоняться от этой абстрактной интерпретации.

Ответ 6

Выражение гарантировано, которое оценивается только один раз потоком управления. Это оправдано в стандарте N4431 §6.4.2/6. Оператор switch [stmt.switch] (Активный удар):

case и метки по умолчанию сами по себе не изменяют поток который продолжает беспрепятственно проходить через такие метки. Чтобы выйти из переключатель, см. разрыв, 6.6.1. [Примечание: обычно, субстанция, которая предмет переключателя является составным и случайным, и появляются метки по умолчанию на операторах верхнего уровня, содержащихся в (составной) субстанция, но это не требуется. Объявления могут появляться в подстановка оператора switch-statement. - конечная нота]