g ++ компилятор: флаг оптимизации добавляет предупреждающее сообщение

Я заметил это интересное поведение g ++ компилятор, если я добавляю флаг-O3 к компилятору, я добираюсь

otsu.cpp:220: warning: ‘x’ may be used uninitialized in this function

Однако, когда я не использую оптимизацию и вместо этого использую флаг отладки-g, я не получил предупреждений вообще. Теперь, я доверяю компилятору больше, когда флаг-g идет; однако, я задаюсь вопросом, является ли это четко определенным поведением, которое должно ожидаться?

Для ясности код, который вызывает это, является чем-то вдоль этих строк:

int x; //uninitialized


getAValueForX( &x ); // function makes use of x,
                     // but x is unitialized

где

 void getAValueForX( int *x )
 {
     *x = 4;
 }

или что-то вдоль тех строк, очевидно, более сложных.

6
задан ldog 27 January 2010 в 00:16
поделиться

7 ответов

Ожидается. Оптимизации вызывают определенный анализ кода для запуска, и именно так GCC находит определенные переменные. Это на странице ручной работы:

. Отказ Отказ Эти предупреждения зависят от оптимизации

http://gcc.gnu.org/onlinedocs/gcc/warning-oftions.html

17
ответ дан 8 December 2019 в 04:08
поделиться

Это на самом деле очень распространено с GCC. И да, это следует ожидать.

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

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

3
ответ дан 8 December 2019 в 04:08
поделиться

Мои флаги компилятора:

CFLAGS=-W -Wall\
 -Wno-non-template-friend\
 -Wold-style-cast\
 -Wsign-promo\
 -Wstrict-null-sentinel\
 -Woverloaded-virtual
# -Weffc++

-Weffc++ могут быть очень раздражающими, поэтому иногда я пытаюсь, но обычно держу его выключенным. Попробуйте эти - и другие в руководстве - и давайте посмотрим, что мы видим.

1
ответ дан 8 December 2019 в 04:08
поделиться

Да, это хорошо определенное поведение. Когда GCC-оптимизатор не включен, он не делает определенных типов проверки выполнения-пути (чтобы избежать штрафов за выполнение таких проверок). Определенные ситуации, такие как использование неинициализированных переменных, могут быть обнаружены только при выполнении этих дополнительных проверок. Поэтому с помощью -O0 GCC не может предупредить об этих условиях.

1
ответ дан 8 December 2019 в 04:08
поделиться

Тот факт, что компилятор может перемещать вещи для оптимизации, может вызвать проблемы и привести к неопределенному поведению (как указано ниже в ручных состояниях); я думаю, что было бы полезно посмотреть на код, чтобы попробовать и помочь ему обрести смысл.

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

1
ответ дан 8 December 2019 в 04:08
поделиться

У меня такая же проблема в моем компиляторе MSVC 6. Инициализация рассматриваемой переменной, удаляет возможность плохого пути от точки зрения компилятора.

0
ответ дан 8 December 2019 в 04:08
поделиться

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

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

-121--1262022-

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

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

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

Цитата:

Я доверяю компилятору больше, когда -g Флаг на

, пока верно, что если компилятор имеет ошибку, вполне вероятно, будет в оптимизере (она является самой сложной частью), для зрелого компилятора, такого как GCC, это было бы очень редким нахождением. И наоборот люди часто считают, что их рабочий код не удается при оптимизации; Чаще всего код всегда был ошибочен (возможно, он полагался на неопределенное или определенное поведение компилятора), и Optimizer только что разоблачил этот недостаток. Поэтому я предлагаю, если вы найдете свой код, разбитый под оптимизацией, подозреваете код до того, как подборщик - бритва Commiler - Occam.

3
ответ дан 8 December 2019 в 04:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: