Следует ли исправлять предупреждения компилятора о преобразованиях типов, используя явные типы типов? - PullRequest
2 голосов
/ 21 декабря 2010

В моем текущем проекте компилятор показывает сотни предупреждений о преобразованиях типов.

Существует много кода, подобного этому

iVar = fVar1*fVar2/fVar3;
// or even
iVar = fVar1*fVar2/fVar3+.5f;

, которые намеренно присваивают float значения int.

Конечно, я мог бы исправить эти предупреждения, используя

iVar = (int)(...);

но это выглядит некрасиво.

Вы бы предпочли жить с безобразием или жить с предупреждениями?
Или есть даже чистый раствор?

Ответы [ 6 ]

12 голосов
/ 21 декабря 2010

Наличие сотен предупреждений, которые не являются проблемой, опасно, однажды предупреждение, которое является реальной проблемой, появится и заглушится шумом.

Оберегайте код от предупреждений.

Если вы знаете, что делаете, добавьте приведение или преобразование.

10 голосов
/ 21 декабря 2010

Да.

Вы должны всегда исправлять предупреждения компилятора.Несколько причин:

*) Это может быть причиной ошибки и нуждаться в реальном исправлении, а не просто в приведении.Вы не узнаете, пока не посмотрите.

*) Фактические ошибки кодирования, которые проявляются в виде предупреждений, могут затеряться в шуме, создаваемом сотнями предупреждений

*) Это ясно для других кодеровчто вы действительно хотели использовать эту переменную неправильного типа / знака.Это преднамеренно.

*) Это ясно и ясно дает понять, что тип и / или подпись изменяется.Если имена ваших переменных не содержат указание типа и подписи, может быть не очевидно, что это происходит.

5 голосов
/ 21 декабря 2010

Я компилирую с «предупреждениями, которые рассматриваются как ошибки».Предупреждения часто указывают на то, что вы написали код, который не будет вести себя так, как вы хотели.

Приведение в этом случае показало бы, что вы меняете тип, что означает изменение в точности (и влияние на производительность, если вы работаете над чрезвычайно критичным по времени кодом).Это всегда хорошая политика - писать код, который показывает все его явные и неявные результаты наиболее наглядным способом, чтобы вы по-прежнему знали, что делает ваш код после того, как его выкопали несколько месяцев спустя - или если член команды должен с ним работать.

2 голосов
/ 21 декабря 2010

На мой взгляд, иногда компиляторы выдают предупреждения о проблемах, которые я считаю не проблемными.В этом случае решение может состоять в том, чтобы отключить эти конкретные предупреждения.Но вы должны проявлять осторожность и быть уверенным, что вы также не скрываете существенных предупреждений.

Для неявных предупреждений о преобразовании типов вы хотите их иногда, но не всегда.Обычно вы хотите игнорировать int для получения конверсий, но слышать о других.В идеале компилятор позволил бы вам настраивать отчеты о предупреждениях на этом уровне детализации.

1 голос
/ 15 сентября 2015

В случае преобразования с плавающей точкой в ​​целое, я думаю, что лучше писать и использовать функции, а не типы; сами функции могут использовать типы типов, но я бы посчитал, что вызов такой функции, как int_round_mid_up(x), лучше, чем (int)(x+0.5), тем более что функцию можно легко написать один раз для правильной обработки положительных и отрицательных чисел, включая предательский 0,499999999999999944 [который при добавлении к 0,5 дает 1,0], в то время как выражение на основе типов (int)(x+0.5) будет неправильно округлять -2,4 до -1. ИМХО, для языка не существует хорошего способа определения типов типов с плавающей точкой в ​​целое (некоторые используют различные формы округления, некоторые усечения, а некоторые могут использовать полы; так как нет ясного «лучшего» способа сделать преобразование, было бы лучше, если бы программист определил, что нужно, а не язык выбирал метод), и поэтому программисты должны избегать их вне очень узкого контекста.

Что касается преобразований между целочисленными типами, предупреждения о сужающихся преобразованиях, как правило, являются хорошими и должны быть разрешены глобально, но локально подавлены с помощью явных типов типов. Для большинства видов числовой работы преобразования из double в float обычно не должны генерировать предупреждения (или, что еще хуже, ошибки), хотя, к сожалению, не все языки или компиляторы позволяют подавлять эти предупреждения независимо от предупреждений для других типов.

Категория преобразований, которая должна быть настроена на генерацию предупреждений для компиляторов, которые ее поддерживают (хотя, увы, многие этого не делают), - это преобразование из узкого выражения, которое может привести к усеченному результату, к типу, который мог бы содержать результат если не усечено, например

uint64_t ul = ui1 - ui2; // With ui1 and ui2 being uint32_t
double d1 = f1 / f2; // With f1 and f2 being float

Если бы я хотел, чтобы поведение, полученное из вышеприведенных выражений, я записал бы их как:

uint64_t ul = (uint32_t)(ui1 - ui2);
double d1 = (float)(f1 / f2);

, поскольку в противном случае программист, увидевший вышеизложенное без типов, может быть склонен переписать их как:

uint64_t ul = (uint64_t)ui1 - ui2;
double d1 = (double)f1 / f2;

, который может привести к поведению, которое, хотя и более желательно, может противоречить тому, что на самом деле нужно программе.

1 голос
/ 10 февраля 2011

Рекомендуется включить предупреждения для любого сужающегося неявного преобразования типа, то есть любого преобразования, для которого преобразованный в тип не может содержать все значения исходного типа.Это включает, например, преобразования с плавающей точкой в ​​int и преобразования в любом направлении между подписанным int и unsigned int.Эти преобразования могут привести к переполнению и / или потере информации, поэтому их всегда следует указывать явно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...