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

C++

Войти
Регистрация
Восстановить пароль
 
 
Kastaneda
Форумчанин
Эксперт С++
4511 / 2853 / 227
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
#1

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

17.12.2015, 06:59. Просмотров 607. Ответов 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 по сути используется по дефолту.

Как получить заветный мусор на выходе?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.12.2015, 06:59     Не могу заставить g++ не инициализировать локальную переменную нулем
Посмотрите здесь:
C++ Не получается инициализировать переменную
C++ Инициализировать переменную ее максимально допустимым значением
Как (можно ли) инициализировать переменную в структуре? C++
C++ Возвращение ссылки на локальную переменную
Возврат ссылки на локальную переменную C++
C++ Требуется только объявить переменную, инициализировать ее не нужно
C++ VS2010 отладчик не видит локальную переменную
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kastaneda
Форумчанин
Эксперт С++
4511 / 2853 / 227
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
19.12.2015, 04:41  [ТС]     Не могу заставить g++ не инициализировать локальную переменную нулем #16
Спасибо, теперь понятно
Цитата Сообщение от Evg Посмотреть сообщение
и вот такое для gcc-4.1.2
У меня в 4.9 такой же код генерится.
Evg
Эксперт CАвтор FAQ
17537 / 5775 / 370
Регистрация: 30.03.2009
Сообщений: 15,904
Записей в блоге: 26
19.12.2015, 12:54     Не могу заставить g++ не инициализировать локальную переменную нулем #17
gcc-4.9 у меня только 64-битный компилятор, там так:

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

Код
        pushl   $0
        pushl   $.LC0
        call    printf
Kastaneda
Форумчанин
Эксперт С++
4511 / 2853 / 227
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
19.12.2015, 13:57  [ТС]     Не могу заставить g++ не инициализировать локальную переменную нулем #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]) интуитивно напоминает обнуление, не?
Evg
Эксперт CАвтор FAQ
17537 / 5775 / 370
Регистрация: 30.03.2009
Сообщений: 15,904
Записей в блоге: 26
19.12.2015, 14:38     Не могу заставить g++ не инициализировать локальную переменную нулем #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 распределилась в стеке, может ты оптимизации не включил?
Kastaneda
Форумчанин
Эксперт С++
4511 / 2853 / 227
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
19.12.2015, 14:40  [ТС]     Не могу заставить g++ не инициализировать локальную переменную нулем #20
Цитата Сообщение от Evg Посмотреть сообщение
может ты оптимизации не включил?
да, не включил, специально, чтоб посмотреть будет ли обнуляться.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2015, 15:01     Не могу заставить g++ не инициализировать локальную переменную нулем
Еще ссылки по теме:
C++ Передать локальную переменную в новую функцию
Ошибка E2363 Попытка возвратить локальную переменную C++
Как инициализировать глобальную переменную в зависимости от количества строк в файле C++
Как в данном контексте правильно разместить статическую локальную переменную? C++
Как локальную переменную сделать глобально, при это сохранив накопленное в ней значение? C++

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17537 / 5775 / 370
Регистрация: 30.03.2009
Сообщений: 15,904
Записей в блоге: 26
19.12.2015, 15:01     Не могу заставить g++ не инициализировать локальную переменную нулем #21
Ну дык:

C
static bool
gate_initialize_regs (void)
{
  return optimize > 0;
}
В режиме без оптимизаций эта функциональность и не запускается. Тем более, что в режиме без оптимизаций там всё в стек складывается скорее всего. Если я правильно понял комментарий, то инициализацию регистров они делают для упрощения некоторых оптимизаций. Написали, что есть побочный эффект в виде детерминированного поведения программ с неинициализированными переменными, но типа крутые пацаны умеют читать warning'а, а лохи нас не интересуют
Yandex
Объявления
19.12.2015, 15:01     Не могу заставить g++ не инициализировать локальную переменную нулем
Ответ Создать тему
Опции темы

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