Почему моя переменная инициализируется в режиме отладки, а не в режиме выпуска? - PullRequest
2 голосов
/ 21 декабря 2011

У меня есть приложение Windows Form, созданное с использованием VC ++ dot net 3. Существует целочисленная переменная, скажем, int x.

Когда я запускаю приложение в режиме отладки, значение для x = 0; Но когда я запускаю приложение без отладки, значение огромно 113901996.

переменная инициализируется как int x = 0

Почему это так? Какие настройки мне нужно проверить?

Ответы [ 2 ]

3 голосов
/ 21 декабря 2011

РЕДАКТИРОВАТЬ: Согласно вашей новой информации, которую вы забыли инициализировать переменную, поведение ожидается. Вы читаете мусорную память.

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

Вы на самом деле используете x? Если вы просто инициализируете его, оптимизатор, скорее всего, исключит все это.

Если это не влияет на наблюдаемое поведение программы, оптимизатор может свободно вырезать что-либо из двоичного файла.

Часы могут также лгать вам, я видел, что это происходит в режиме выпуска.

Можете ли вы опубликовать минимальный код, который воспроизводит проблему?

Если вы протестируете его с каким-либо выводом, то есть:

cout << x;

Я уверен, вы увидите, что x это 0.

EDIT:

Просто чтобы прояснить ситуацию:

int main()
{
   int x = 0;
   x = 3;
   return 0;
}

будет переводиться в (в режиме релиза, с полной оптимизацией):

00401000  xor         eax,eax 
00401002  ret  

Переменная не только не назначена, она даже не существует ; в отличие от отладочной версии:

00411370  push        ebp  
00411371  mov         ebp,esp 
00411373  sub         esp,0CCh 
00411379  push        ebx  
0041137A  push        esi  
0041137B  push        edi  
0041137C  lea         edi,[ebp-0CCh] 
00411382  mov         ecx,33h 
00411387  mov         eax,0CCCCCCCCh 
0041138C  rep stos    dword ptr es:[edi] 
0041138E  mov         dword ptr [x],0 
00411395  mov         dword ptr [x],3 
0041139C  xor         eax,eax 

где переменная x создается и присваивается дважды (см. mov dword ptr [x],0 и mov dword ptr [x],3).

Если наблюдаемый результат изменяется с помощью переменной, то есть ::

int main()
{
   int x = 0;
   x = 3;
   cout << x;
   return 0;
}

сгенерированный двоичный файл будет выглядеть так:

00401000  mov         ecx,dword ptr [__imp_std::cout (40203Ch)] 
00401006  push        3    
00401008  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> 
0040100E  xor         eax,eax 

видите, что даже при этом x на самом деле не генерируется, а вместо этого 3 помещается в стек и печатается напрямую.

Но наблюдаемое поведение в этом случае остается тем же, поскольку 3 печатается. Для пользователя не имеет значения, печатается ли значение x, которое должно быть 3, или печатается 3 напрямую,

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

0 голосов
/ 21 декабря 2011

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

Это способ заставить пользователя инициализировать все свои переменные. В C ++ вы действительно ДОЛЖНЫ. Для других языков, таких как C #, по умолчанию будет 0 / какое-то другое значение по умолчанию для вас, но в C ++ вам решать.

Я полагаю, у вас проблема с инициализацией. Вы говорите, что назначаете начальное значение 0, однако, когда вы измеряете, вы получаете 11301996. Либо вы не инициализируете, как вы ожидаете (мой лучший выбор), либо есть проблема с вашей программой вывода / тестирования. Разместите свой код, и я буду рад помочь вам в дальнейшем.

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

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