Visual C ++, кажется, инициализирует нулями POD-члены класса, чего не следует - PullRequest
2 голосов
/ 19 апреля 2019

У меня есть такой класс:

class TestClass
{
public:
    TestClass() {};
    //Note: I wish not to initialize rawMemory (for whatever reason)
    int rawMemory[32];
};

int main()
{
    TestClass obj;
    return 0;
}

И после того, как я создал TestClass объект, используя TestClass obj;, я получил желаемое поведение: rawMemory не инициализировался (заполненный 0xcc в режиме отладки и случайным неопределенным значением в режиме выпуска).
Но когда я добавил указатель на класс:

class TestClass
{
public:
    TestClass() {};
    int rawMemory[32];
    int* ptr;
};

rawMemory инициализирован до нуля! Я думаю, что в соответствии со стандартом этого не должно произойти. Я даже попробовал с std::aligned_storage, который предназначен для резервирования неинициализированной автоматической памяти, а rawMemory все еще инициализируется нулями!

class TestClass
{
public:
    TestClass() {};
    std::aligned_storage<sizeof(int), alignof(int)>::type rawMemory[32];
    int* ptr;
};

Примечание: я пробовал g ++, он работал как я ожидал.
Обновление: если я изменю TestClass на структуру, проблема исчезнет; Если я дам TestClass неявный конструктор по умолчанию, проблема исчезнет.

1 Ответ

3 голосов
/ 19 апреля 2019

Наконец-то я нашел источник этой проблемы.
Когда в классе присутствует указатель, Visual C ++ вставляет вызов метода autoclassinit перед вызовом конструктора, который я определил.Этот вызов метода несколько спутал с инициализацией члена, и он инициализировал нулем мой rawMemory member .
Это поведение можно удалить, отключив /sdl в параметрах компилятора Visual C ++.Однако, если это не очень критично для производительности (или узкое место), я предлагаю оставить все как есть.
Спасибо всем, кто пытался помочь!

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