Недавно я допустил синтаксическую ошибку, написав это:
b = (float)a*0,1;
вместо:
b = (float)a*0.1;
Я с удивлением обнаружил, что в первой строке даже нет ошибки компиляции. Меня еще больше сбивает с толку тот факт, что следующая строка приводит к ошибке компиляции:
float b = (float)a*0,1;
Может кто-нибудь объяснить мне, почему третья строка является синтаксической ошибкой, а не первой (на самом деле это так)?
Пример компилятора, настроенного на выдачу предупреждения: godbolt.org/z/jrrE7bnEW
оффтоп: если a
— целое число, приведение не нужно. А когда вам понадобится гипс, лучше использовать подходящий static_cast<float>(a)
Это подпадает под оператор запятая.
Оператор запятая делит выражение на две части:(float) a * 0
и 1
.
Они оцениваются отдельно.
Этот ...
b = (float)a*0,1;
... это заявление. В частности, выражение-выражение. В выражении внутри запятая (,) является оператором с выражениями операндов b = (float)a*0
и 1
. Общее утверждение эквивалентно
b = (float)a*0; 1;
, а само выражение с запятой принимает значение второго операнда (1), которое в этом случае игнорируется.
С другой стороны, это...
float b = (float)a*0,1;
... является (неверно сформированным) объявлением. Запятая здесь — это не оператор-запятая, а разделитель между объявляемыми элементами. Это объявление ошибочно, поскольку второй элемент не содержит декларатора, обозначающего объявляемый элемент. (Декларатором в первом пункте является b
.)
Иногда вы получаете предупреждение компилятора (обычно что-то вроде
blah
не имеет никакого эффекта), но когда компилятор видит синтаксически правильный код, каким бы ошибочным он ни был логически, он компилирует его.