Чтобы описать проблему просто, взгляните на код ниже:
int main()
{
int a=123;
({if (a) a=0;});
return 0;
}
Я получил это предупреждение от [-Wsequence-point]
Line 4: warning: operation on 'a' may be undefined
моя версия g ++ 4.4.5
Я буду признателен, кто бы ни объяснил эту простую проблему.
Кстати, вы можете найти мою оригинальную программу и оригинальную проблему в # 7 в этот Китайский сайт (не обязательно)
UPD1:
хотя, чтобы изменить код в ({if(a) a=0; a;})
можно избежать предупреждения, но я осознал, что настоящей причиной проблемы может быть не The last thing in the compound statement should be an expression followed by a semicolon
,
потому что документальный фильм также сказал If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value
,
пример может показать это:
int main()
{
int a=123, b;
({;});
({if (a) b=0;});
return 0;
}
и этот код получил нет предупреждений!
так что я думаю, что настоящая причина — это что-то в точке последовательности.
пожалуйста помоги!
UPD2:
извините @AndyProwl за то, что он не принял его ответ, который был принят до UPD1. следуя его совету, я могу задать новый вопрос (UPD1 — новый вопрос, отличный от исходного). Я приму его ответ снова, потому что он, безусловно, избегает предупреждений. 🙂
Если я решу задать новый вопрос, я обновлю этот вопрос, чтобы добавить ссылку.
Согласно грамматике C ++, выражения (возможно, кроме лямбда-выражений, но это другая история) не могут содержать операторов — включая операторы блоков. Поэтому я бы сказал, что ваш код некорректен, и если GCC компилирует его, это означает, что это (странное) расширение компилятора.
Вам следует обратиться к справочнику компилятора, чтобы выяснить, какая семантика ему дана (или не дана, как, кажется, подсказывает сообщение об ошибке).
РЕДАКТИРОВАТЬ:
Как отметил Шафик Ягмур в комментариях, похоже, это расширение GNU. Согласно документация, значение этого «выражения выражения» должно быть значением последнего выражения в блоке, которое должно быть выражением выражения:
Последним в составном операторе должно быть выражение, за которым следует точка с запятой; значение этого подвыражения служит значением всей конструкции. (Если вы используете какой-то другой вид оператора последним в фигурных скобках, конструкция имеет тип void, и, следовательно, фактически не имеет значения.)
Поскольку блок в вашем примере не содержит оператор выражения в качестве последнего оператора, GCC не знает, как оценить это «выражение оператора» (не путать с «выражением выражения» — это то, что должно появляться последним в выражении оператора) ,
Поэтому, чтобы GCC не жаловался, вы должны сделать что-то вроде:
({if (a) a=0; a;});
// ^^
Но, честно говоря, я не понимаю, зачем кому-то это понадобится в C ++.
Других решений пока нет …