Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Kastaneda
Jesus loves me
Эксперт С++
4689 / 2893 / 236
Регистрация: 12.12.2009
Сообщений: 7,354
Записей в блоге: 2
Завершенные тесты: 1
#1

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

17.12.2015, 06:59. Просмотров 673. Ответов 20
Метки нет (Все метки)

Привет!
Есть такой код (из серии "что будет напечатано на экран")
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
 
int x = 1;
 
namespace A
{
int x = 2;
}
 
int main() 
{
    int x = x;
    cout << x << endl;
    return 0;
}
Ожидается мусор, но g++ и clang++ упорно выводят 0, мусор выводит только MSVC. Посмотрел ассемблерный выхлоп, g++ просто берет 4 байта со стека и печатает их (почему-то на стеке оказывается 0), clang++ явно пишет 0 на стек (т.е. явно инициализирует).
В g++ собирают так
Bash
1
g++ -Wall -pedantic-errors -std=c++11 -O2 -fno-init-local-zero tmp.cpp
варнинги просто чтоб посмотреть на уровень предупреждений, а стандарт указал, чтоб он gnu'шные фичи не использвоал (мало ли), оптимизация понятно для чего (чтоб не дебаг)). -fno-init-local-zero по сути используется по дефолту.

Как получить заветный мусор на выходе?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.12.2015, 06:59
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не могу заставить g++ не инициализировать локальную переменную нулем (C++):

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

Как (можно ли) инициализировать переменную в структуре? - C++
Как пример struct cifri { char one=&quot;ONE&quot;; }; Почему так нельзя и как можно?

Инициализировать переменную ее максимально допустимым значением - C++
Максимальное значение для unsigned int = 65535, а нельзя инициализировать переменную заданного типа максимальным значением? Например,...

Возвращение ссылки на локальную переменную - C++
Заметил недавно одну интересную вещь. Как вообще работает такой код? Причем коректно. int&amp; func(); int main() { cout &lt;&lt; func(); ...

Возврат ссылки на локальную переменную - C++
Привет, есть такой код: int*&amp; change(void) { int* x(new int(50)); return x; } int main(void) {

Требуется только объявить переменную, инициализировать ее не нужно - C++
по модификатору const. Объявите переменную c именем m, в которой хранится указатель на двумерный массив целых чисел (int), выделенный в...

20
Kastaneda
Jesus loves me
Эксперт С++
4689 / 2893 / 236
Регистрация: 12.12.2009
Сообщений: 7,354
Записей в блоге: 2
Завершенные тесты: 1
19.12.2015, 04:41  [ТС] #16
Спасибо, теперь понятно
Цитата Сообщение от Evg Посмотреть сообщение
и вот такое для gcc-4.1.2
У меня в 4.9 такой же код генерится.
0
Evg
Эксперт CАвтор FAQ
18242 / 6367 / 435
Регистрация: 30.03.2009
Сообщений: 17,610
Записей в блоге: 28
19.12.2015, 12:54 #17
gcc-4.9 у меня только 64-битный компилятор, там так:

Код
        xorl    %esi, %esi  <-- обнуление
        movl    $_ZSt4cout, %edi
        call    _ZNSolsEi
Добавлено через 2 минуты
На gcc-4.9 в режиме 32 компилятор работает, просто нету хидеров. Аналогичный код на Си даёт такой ассемблер:

Код
        pushl   $0
        pushl   $.LC0
        call    printf
0
Kastaneda
Jesus loves me
Эксперт С++
4689 / 2893 / 236
Регистрация: 12.12.2009
Сообщений: 7,354
Записей в блоге: 2
Завершенные тесты: 1
19.12.2015, 13:57  [ТС] #18
Станно, вот у меня в 4.9.2
Assembler
1
2
3
4
5
6
7
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    movl    $_ZSt4cout, %edi
    call    _ZNSolsEi
обнуления нет

Добавлено через 5 минут
Evg, не умею читать лиспоподобную портянку (похоже это AST?), которую ты показал выше (-da), но в файле tmp.cpp.236r.stack нашел такое
Код
(insn 5 2 6 2 (set (reg:SI 0 ax [85])
        (mem/c:SI (plus:DI (reg/f:DI 6 bp)
                (const_int -4 [0xfffffffffffffffc])) [0 x+0 S4 A32])) tmp.cpp:6 90 {*movsi_internal}
     (nil))
Чтоб было понятно, что такое tmp.cpp:6 вот мой код
C++
1
2
3
4
5
6
7
8
#include <iostream>
 
int main() 
{
    int x = x;
    std::cout << x;
    return 0;
}
вот это (reg:SI 0 ax [85]) интуитивно напоминает обнуление, не?
0
Evg
Эксперт CАвтор FAQ
18242 / 6367 / 435
Регистрация: 30.03.2009
Сообщений: 17,610
Записей в блоге: 28
19.12.2015, 14:38 #19
Цитата Сообщение от Kastaneda Посмотреть сообщение
Evg, не умею читать лиспоподобную портянку (похоже это AST?)
Это rtl. Один узел представления (insn) является как бы деревом. Если отформатировать, то выглядит так

Код
set (reg:SI 0 ax [85])
    (mem/c:SI (plus:DI (reg/f:DI 6 bp)
                       (const_int -4 [0xfffffffffffffffc]))
Т.е. записать в reg85 (%ax) значение из адреса reg6 (%bp) плюс (-4). Т.е. из стека со смещением -4 считывается значение и записывается в регистр. Видимо, переменная x распределилась в стеке, может ты оптимизации не включил?
2
Kastaneda
Jesus loves me
Эксперт С++
4689 / 2893 / 236
Регистрация: 12.12.2009
Сообщений: 7,354
Записей в блоге: 2
Завершенные тесты: 1
19.12.2015, 14:40  [ТС] #20
Цитата Сообщение от Evg Посмотреть сообщение
может ты оптимизации не включил?
да, не включил, специально, чтоб посмотреть будет ли обнуляться.
0
Evg
Эксперт CАвтор FAQ
18242 / 6367 / 435
Регистрация: 30.03.2009
Сообщений: 17,610
Записей в блоге: 28
19.12.2015, 15:01 #21
Ну дык:

C
static bool
gate_initialize_regs (void)
{
  return optimize > 0;
}
В режиме без оптимизаций эта функциональность и не запускается. Тем более, что в режиме без оптимизаций там всё в стек складывается скорее всего. Если я правильно понял комментарий, то инициализацию регистров они делают для упрощения некоторых оптимизаций. Написали, что есть побочный эффект в виде детерминированного поведения программ с неинициализированными переменными, но типа крутые пацаны умеют читать warning'а, а лохи нас не интересуют
0
19.12.2015, 15:01
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2015, 15:01
Привет! Вот еще темы с ответами:

VS2010 отладчик не видит локальную переменную - C++
Добрый день! С чем это может быть связано?

Передать локальную переменную в новую функцию - C++
#include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;windows.h&gt; using namespace std; int...

Ошибка E2363 Попытка возвратить локальную переменную - C++
Такую ошибку выдает компилятор Embarcadero, в Студии почему то ее не выдает, мне нужно сделать так чтобы и в эмбаркадеро не выдавало...

Как инициализировать глобальную переменную в зависимости от количества строк в файле - C++
Есть переменная типа int glob = 3; объявлена в не main(), т.е. глобальная. После неё, тоже не в mаin, объявлены структуры ex: struct...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
21
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru