Ниже приведена некоторая история этого синтаксиса.
В классическом C, обработка ошибок часто делается, написав что-то вроде:
int error;
...
if(error = foo()) {
printf("An error occured: %s\nBailing out.\n", strerror(error));
abort();
}
Или, когда там было вызов функции, которая может возвращать пустой указатель, идиома была использована наоборот:
Bar* myBar;
... //in old C variables had to be declared at the start of the scope
if(myBar = getBar()) {
//do something with myBar
}
Однако этот синтаксис опасно близко к
if(myValue == bar()) ...
, поэтому многие люди рассматривают назначение в состоянии плохого стиля, и компиляторы начали предупреждать об этом (по крайней мере, с -Wall
).Тем не менее, это предупреждение можно избежать, добавив дополнительный набор скобок:
if((myBar = getBar())) { //tells the compiler: Yes, I really want to do that assignment!
Тогда C99 пришли вокруг, что позволяет смешивать определения и утверждения, поэтому многие разработчики часто пишут что-то вроде
Bar* myBar = getBar();
if(myBar) {
который чувствует себя неловко. Поэтому новый стандарт позволяет определения внутри условий, чтобы обеспечить короткий, изящный способ сделать это:
if(Bar* myBar = getBar()) {
Там нет никакой опасности в этом заявлении больше, вы явно даете переменному тип, явно желая его инициализироваться. Он также избегает дополнительной строки для определения переменной, что приятно. Но самое главное, что компилятор может теперь легко поймать такую ошибку:
if(Bar* myBar = getBar()) {
...
}
foo(myBar->baz); //compiler error
//or, for the C++ enthusiasts:
myBar->foo(); //compiler error
Без определения переменной внутри if
заявления, это условие не будет обнаружено.
Чтобы сделать длинный ответ коротким: Синтаксис в вашем вопросе является продуктом простоты и силы старого C, но он злой, поэтому компиляторы могут предупредить об этом. Поскольку это также очень полезный способ выразить общую проблему, теперь существует очень краткий, надежный способ добиться такого же поведения. И для этого есть много хороших, возможных применений.
В зависимости от того, мой компилятор выдает предупреждение, когда a = b –
Компилятор не выпускает диагностику, потому что это не обязательно. Это вполне допустимый код на C++. –
Следует отметить, что с предупреждениями вы можете, как правило, понять это, компилируя время. – Rapptz