Подтвердить что ты не робот

Что это значит? int foo = foo + 4;

#include <iostream>

int main(int argc, char** args) {
  int foo = foo + 4;
  std::cout << foo << std::endl;
}

И следующий вопрос: есть ли флаг компилятора, чтобы остановить подобное? Я обнаружил, что -Word работает иногда, лучше было бы предотвратить это полностью.

My compiler:  
g++ -v  
Using built-in specs.  
Target: i486-linux-gnu  
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu  
Thread model: posix  
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)  
4b9b3361

Ответ 1

Нет никакого гарантированного способа остановить подобное. Это неотъемлемая часть С++ и C, что имя переменной видно в ее инициализаторе. Это позволяет делать такие вещи, как

T *t = malloc(sizeof(*t));

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

Он также действителен в другом контексте.

Изменить: уточнить - поведение вашего фрагмента undefined: вы читаете значение не инициализированной переменной. Эти компиляторы не обязаны диагностировать это не означает, что поведение определено.

Ответ 2

int foo = foo + 4;

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

Ответ 3

Я могу поспорить, что это означает поведение undefined.

Изменить: см. цитату из ответ на другой вопрос.

Изменить: скорее всего, значение в RHS берется из неинициализированной ячейки памяти в стеке, к ней добавляется 4, и результат используется для инициализации.

Ответ 4

Чтобы получить предупреждение от gcc для этого конкретного кода, вам нужно -Wuninitialized (-Wall включает это) и -O (или любой уровень оптимизации выше 0).

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

Ответ 5

Я бы ожидал, что какой-нибудь полуподобный достойный компилятор выдает предупреждение для int foo = foo + 4; в своей конфигурации по умолчанию. У хороших есть варианты отклонить его полностью как "использование неинициализированной переменной" и/или принять какое-либо конкретное происхождение, когда программист точно понимает, что происходит и не беспокоится о неожиданном поведении.

Я, например, часто использовал для записи int toggle = toggle ^ 1 в те дни, когда компиляторы не были такими суетливыми, если бы все, что я хотел, было переключателем переключения, где мне было все равно, он начал ИСТИННО или ЛОЖЬ. В настоящее время я бы, вероятно, написал статический bool toggle = TRUE; переключение = ^ тумблер