...посмотрим внимательно на вывод компилятора при максимально включенных предупреждениях
$ g++ -W -Wall test.cpp
К самой статье это отношения не имеет, но хочется заметить, что заблуждение насчет максимально включенных предупреждений компилятора встречается довольно часто —
-Wall
и -Wextra
(-W
) это еще не все предупреждения. К сожалению, путаница по большей части возникает из-за разработчиков GCC. Начать с того, что имя опции -Wall
само по себе вводит в заблуждение, так они еще добавляют или удаляют предупреждения от версии к версии, или вообще меняют их смысл, чем лично меня иногда просто ставят в тупик. Но надо отдать им должное — компилятор все-таки развивается, и сейчас с помощью предупреждений можно узнать гораздо больше, чем в более ранних версиях.Например, в последней версии GCC (4.4) есть полезные предупреждения, которые нужно включать самостоятельно:
-Wcast-qual
Предупреждает о преобразованиях типа "из const char * в char *".-Wconversion
Предупреждает, если при преобразовании типов может произойти потеря данных. Например, при преобразовании из long в short.-Wredundant-decls
Предупреждает об повторном объявлении чего-нибудь в той же области видимости, даже если это ни на что не влияет.-Wshadow
Предупреждает, если объявление переменной перекрывает объявленную ранее переменную с таким же именем.-Wsign-conversion
Предупреждает, если результат выражения может изменить знак. Например, при преобразовании из int в unsigned int.-Wunreachable-code
Предупреждает, если какой-то фрагмент кода никогда не будет выполнен. Например, если перед этим фрагментом стоит return. Этот флаг специально не был включен в группу-Wall
для того, чтобы можно было разделять сборки debug и release.
И еще некоторые другие:
- -Wcast-align
- -Wformat-nonliteral
- -Wformat-security
- -Wformat-y2k
- -Winit-self
- -Wlogical-op
- -Wmissing-format-attribute
- -Wmissing-include-dirs
- -Woverlength-strings
Небольшое дополнение
ОтветитьУдалитьgcc -c -Q -Wall --help=warnings
Я ещё пользуюсь
ОтветитьУдалить-Wlogical-op
-Wabi
-Wctor-dtor-privacy
-Wnon-virtual-dtor
-Wstrict-null-sentinel
-Woverloaded-virtual
-Wpointer-arith
-Wswitch-enum
-Wswitch-default
-Wold-style-cast
Кроме последних трёх они срабатывают крайне редко, но пусть будут.
А когда скучно и нечего делать можно включить -Weffc++ :)
Что касается -Wunreachable-code то он часто ругается на вполне себе reachable-code и доверия к нему у меня нет.
2 Alexander: Спасибо, про флаг -Q я не знал. Очень полезно. И познавательно :)
ОтветитьУдалить2 Игорь Говоров: Странно насчет -Wunreachable-code -- мне ни разу не попадались ошибочные предупреждения. Если у Вас есть пример -- приведите его, плз. Было бы интересно попробовать с разными версиями компилятора.
Сделать синтетический пример на ложное срабатывание на скорую руку лень, может быть позже.
ОтветитьУдалитьНо показать что он любит заваливать вывод бесполезными сообщениями довольно просто (нельзя не <pre> ни <code>? Досадно ):
$ cat unreach.cpp
#include <cstdlib>
#include <string>
#include <iostream>
struct MyStruct
{
std::string a;
};
int main(int /*argc*/, char** /*argv*/)
{
MyStruct s;
std::cout << s.a << std::endl;
return (EXIT_SUCCESS);
}
$g++ -Wall -Wextra -Wunreachable-code unreach.cpp
unreach.cpp: In constructor ‘MyStruct::MyStruct()’:
unreach.cpp:6: warning: will never be executed
Ну вот зачем мне этот Warning про сгенерированный компилятором код?
Да, действительно. Причем версия g++-4.4 лезет еще дальше - в дебри STL. Зачем - непонятно.
ОтветитьУдалитьЗначит, будут исправлять.
Да, забыл написать:
ОтветитьУдалитьgcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux)
Поставил сейчас -Wunreachable-code на один из проектов, почитал. Ругается на вот такой кусок кода:
const QString dir = QFileDialog::getExistingDirectory(0, QString(),QString(""));
У QString все операторы и конструкторы определены, значит дело не в генерируемом коде.
Если убрать "const QString dir = " и оставить только вызов функции то никаких предупреждений не показывается.
В чём дело пока не разобрался, может поковыряю вечером.
Ну, вот в Вашем предыдущем примере предупреждение исправляется, если определить конструктор MyStruct и в нем что-нибудь присвоить а, например a="". Но только какой в этом смысл?
ОтветитьУдалитьДумаю, это действительно баг. На сайте gcc уже есть сообщения, что слишком много предупреждений при использовании STL и gcc-4.4.
2 Alexander: Попробовал -Q на версии 4.1 -- не работает. Похоже, эта фича только в 4.3 появилась. На более ранних версиях -Q имеет какой-то другой смысл, насколько я понял. Хотя, могу и ошибаться.
ОтветитьУдалитьСорри, кажется, я недопонял документацию.
ОтветитьУдалитьВ 4.3 появилась фича --help=... Хотя я был уверен, что в ранних версиях такое тоже можно делать.