Вот MWE чего-то, с чем я столкнулся в коде C ++.
int a = (int)(b/c);
Почему (int)
после оператора присваивания?
Разве не рекомендуется использовать это так?
Это просто типизированный C-стиль. Он используется, чтобы сделать намерения автора явными, особенно когда результат b/c
другого типа (например, unsigned
или же float
).
Без приведения вы часто получаете предупреждение компилятора о неявном преобразовании, которое иногда может иметь последствия. Используя явное приведение, вы заявляете, что согласны с тем, что это преобразование подходит для любых других ограничений, установленных вашей программой, и компилятор выполнит преобразование без выдачи предупреждения.
В C ++ мы используем static_cast<int>(b/c)
сделать актерский состав еще более явным и преднамеренным.
Это не «(int) после оператора присваивания».
Это «(int) перед float — результат ч / с».
Он бросает поплавок в int.
Это приведение, используемое для преобразования переменной или выражения в заданный тип. В этом случае, если b
а также c
были числа с плавающей запятой, добавляя приведение (int)
приводит результат к целому числу.
В частности, это «приведение в стиле C», в современном C ++ есть несколько дополнительных приведений, чтобы дать еще больший контроль (static_cast, dynamic_cast, const_cast и т. Д.)
Это ошибка. В коде:
int a = b/c;
тогда это может привести к неопределенное поведение если результатом деления является значение с плавающей запятой, которое выходит за пределы диапазона int
(например, это превышает INT_MAX
после усечения). Компиляторы могут предупредить об этом, если вы используете флаги предупреждения.
Изменение кода на int a = (int)(b/c);
не влияет на поведение кода, но может привести к тому, что компилятор подавит предупреждение (компиляторы иногда воспринимают приведение как программиста, выражающего намерение, что они не хотят видеть предупреждение).
Так что теперь у вас просто тихое неопределенное поведение, если предыдущий код не был разработан таким образом, что результат деления никогда не может быть вне диапазона.
Лучшее решение проблемы:
long a = std::lrint(b/c);
Если частное находится вне диапазона, то это будет хранить неопределенное значение в a
и вы можете обнаружить ошибку, используя обработку ошибок с плавающей запятой. Ссылка для std :: lrint