Форум программистов, компьютерный форум CyberForum.ru

Не могу заставить g++ не инициализировать локальную переменную нулем - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ AllocHook http://www.cyberforum.ru/cpp/thread1615167.html
Помнится в какой-то теме были задачи одного из собеседований озвучены. Из-за давности той темы отдельно создал новую. Заинтересовала меня тогда одна задача. Определить сколько памяти израсходовал map при выделении 1000000 разных записей. Вот я нашел решение, которое годится для общего случая со своими allocator например. #include <crtdbg.h> #pragma push_macro("_DEBUG") #undef _DEBUG...
C++ Сделать блок-схему для курсовой Если вас не затруднит, прошу сделать блок схему к данной программе #include <conio.h> #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <time.h> /*Размерность матрицы*/ #define N 5 #define M 5 http://www.cyberforum.ru/cpp/thread1614220.html
Запуск проекта в clion C++
Всем привет! У меня такая проблема: не могу запустить проект в clio, когда я запускаю проект вылетает окно edit configuration, а я вообще незнаю что туда писать( Помогите пожалуйста! Заранее спасибо)
Как запустить стороннюю программу с атрибутами? C++
Ребята спасайте, вот получается есть такой код в батнике: plink.exe -ssh 209.249.30.190 -C -N -l adm -pw adm -D 8081 -v Как я понимаю, мы открываем файл plink.exe с нужными нам атрибутами. Как точно так же передать эти атрибуты, только через сишку. Что бы например мы могли передавать атрибуты так: plink.exe -ssh edit1.text -C -N -l edit2.text -pw edit3.text -D 8081 -v
C++ Обмен данными через параллельный порт http://www.cyberforum.ru/cpp/thread1611962.html
Нужен код программы, которая будет обмениваться данными с устройством, подключенное через параллельный порт Добавлено через 14 часов 41 минуту В частности обмен данными с флешкой или принтером
C++ Изменение заголовка окна программы в консоли Здравствуйте. Нужна помощь. Как сделать так, чтобы окно программы в консоли было подписано названием моей программы, а не путём к ней. Можно, конечно, сделать так: #include <iostream> #include <conio.h> #include <windows.h> using namespace std; int main() { system("title Название программы"); подробнее

Показать сообщение отдельно
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16945 / 5350 / 329
Регистрация: 30.03.2009
Сообщений: 14,384
Записей в блоге: 26
18.12.2015, 17:43     Не могу заставить g++ не инициализировать локальную переменную нулем
Если посмотрим на ассемблерный код, то увидим вот такое для компилятора gcc-4.8.0:

Код
...
main:
...
	movl	$0, 4(%esp)
	movl	$_ZSt4cout, (%esp)
	call	_ZNSolsEi
...
и вот такое для gcc-4.1.2

Код
...
main:
...
	<нет записей в %eax>
	movl	%eax, 4(%esp)
	movl	$_ZSt4cout, (%esp)
	call	_ZNSolsEi
...
Другими словами 0 для gcc-4.8.0 (и, видимо, более поздних версий) является никаким не мусором, а какой-то работой со стороны компилятора. Возможно, что это есть борьба с идиотами, которые кричат "на MSVS у меня всё работало, а на gcc не работает", не понимая, что в debug-версиях MSVS все локалы по умолчанию обнуляются (может это и не MSVS, а Borland, я не помню). Возможно, что это сделано для удобства самогО компилятора, чтобы ему не работать с неинициализированными переменными (с ними неудобно строить всякие потоковые графы и прочие конструкции, с которыми работает компилятор). Возможно, что ещё какая-то нанотехнология

Добавлено через 16 минут
Запустил с опцией -da, чтобы посмотреть промежуточное представление. Использовал sparc'овскую версию, т.к. она мне более понятна

--------------------------

Файл t.cc.192r.fwprop2

Код
<нет записей в reg 109>
...
(insn 5 2 6 2 (set (reg:DI 112 [ x+-4 ])
        (sign_extend:DI (reg/v:SI 109 [ x ]))) t.cc:14 145 {*sign_extendsidi2_insn}
     (expr_list:REG_DEAD (reg/v:SI 109 [ x ])
        (nil)))
...
(insn 8 7 9 2 (set (reg:DI 9 %o1)
        (reg:DI 112 [ x+-4 ])) t.cc:14 72 {*movdi_insn_sp64}
     (expr_list:REG_DEAD (reg:DI 112 [ x+-4 ])
        (nil)))
(call_insn 9 8 12 2 (parallel [
            (set (reg:DI 8 %o0)
                (call (mem:DI (symbol_ref:DI ("_ZNSolsEi")
...
insn 5 - пересылка неинициализированного виртуального регистра 109 в виртуального регистр 112
insn 8 - пересылка виртуального регистра 109 в физический регистр %o1 (формирование 2-го параметра call'а)
insn 9 - call

Т.е. тут пока ещё работаем с неициализированными значениями

--------------------------

Файл t.cc.194r.init-regs

Код
...
(insn 23 2 5 2 (set (reg/v:SI 109 [ x ])
        (const_int 0 [0])) t.cc:14 -1
     (nil))
(insn 5 23 6 2 (set (reg:DI 112 [ x+-4 ])
        (sign_extend:DI (reg/v:SI 109 [ x ]))) t.cc:14 145 {*sign_extendsidi2_insn}
     (expr_list:REG_DEAD (reg/v:SI 109 [ x ])
        (nil)))
...
(insn 8 7 9 2 (set (reg:DI 9 %o1)
        (reg:DI 112 [ x+-4 ])) t.cc:14 72 {*movdi_insn_sp64}
     (expr_list:REG_DEAD (reg:DI 112 [ x+-4 ])
        (nil)))
(call_insn 9 8 12 2 (parallel [
            (set (reg:DI 8 %o0)
                (call (mem:DI (symbol_ref:DI ("_ZNSolsEi")
...
Видим по сути всё то же самое, но появился insn 23, в котором выполняется инициализация нулём виртуального регистра 109

--------------------------

С учётом названия фазы "init-regs" похоже и вправду в компиляторе есть фаза заливания нулём всех неинициализированных виртуальных регистров

Добавлено через 9 минут
Исходники gcc-4.8.0. Файл gcc-4.8.0/gcc/init-regs.c

Комментарий в самом начале

C
/* Check all of the uses of pseudo variables.  If any use that is MUST
   uninitialized, add a store of 0 immediately before it.  For
   subregs, this makes combine happy.  For full word regs, this makes
   other optimizations, like the register allocator and the reg-stack
   happy as well as papers over some problems on the arm and other
   processors where certain isa constraints cannot be handled by gcc.
   These are of the form where two operands to an insn my not be the
   same.  The ra will only make them the same if they do not
   interfere, and this can only happen if one is not initialized.
 
   There is also the unfortunate consequence that this may mask some
   buggy programs where people forget to initialize stack variable.
   Any programmer with half a brain would look at the uninitialized
   variable warnings.  */
Условие применимости

C
static bool
gate_initialize_regs (void)
{
  return optimize > 0;
}
Для сравнения заглянул в соседний файл dce.c (dead code elimination). В нём условие срабатывания вот такое

C
static bool
gate_fast_dce (void)
{
  return optimize > 0 && flag_dce
    && dbg_cnt (dce_fast);
}
Похоже на то, что для отключения dce опция у компилятора есть, а отключить init-regs нельзя, только в виде отключения оптимизаций

Добавлено через 15 минут
Цитата Сообщение от Kastaneda Посмотреть сообщение
Вот это << &x убрать и будет 0 на выходе
С учётом вышенаписанного тут попросту не применяется init-regs, т.к. переменная попадает не на виртуальный регистр, а напрямую в стек (из-за взятия адреса)

Добавлено через 2 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
Kastaneda, я как-то тоже хотел в этом разобраться, в общем, вот этот ответ более менее меня успокоил:
http://stackoverflow.com/questions/1...n-ubuntu-linux
Про инициализацию стека - полная бредятина, пример из поста #11 налгядно это демонстрирует
 
Текущее время: 15:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru