Что делает следующие фразы означают в C++: нуль - значение по умолчанию - и инициализация значения?

Изменение, когда это не было должно, может произойти по причинам кроме изменений макета класса - проблема состоит в том, что это - зависящий от реализации компилятор. Если Вы действительно отлаживаете с Eclipse, но делаете производственные сборки с javac, Вы можете заканчивать с двумя несовместимыми наборами данных.

183
задан Destructor 10 March 2016 в 09:27
поделиться

2 ответа

Одно Чтобы понять, что «инициализация значения» является новой в стандарте C ++ 2003 - ее не существует в исходном стандарте 1998 года (я думаю, что это может быть единственная разница, которая больше, чем пояснение). См. Ответ Кирилла В. Лядвинского , где приведены определения прямо из стандарта.

Обязательно нужно знать, что MSVC следует правилам C ++ 98, даже в VS 2008 (VC 9 или cl.exe версии 15.x).

Следующий фрагмент показывает, что MSVC и Digital Mars следуют правилам C ++ 98, в то время как GCC 3.4.5 и Comeau следуют правилам C ++ 03:

#include <cstdio>
#include <cstring>
#include <new>

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

int main()
{
    char buf[sizeof(B)];
    std::memset( buf, 0x5a, sizeof( buf));

    // use placement new on the memset'ed buffer to make sure 
    //  if we see a zero result it's due to an explicit 
    //  value initialization
    B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                            //C++03 rules - pB->m is set to 0
    std::printf( "m  is %d\n", pB->m);
    return 0;
}
64
ответ дан 23 November 2019 в 06:01
поделиться

C ++ 03 Standard 8.5 / 5:

Чтобы инициализировать нулём объект тип T означает:
- если T - скалярный тип (3.9), объекту присваивается значение 0 (ноль), преобразованное в T;
- если T - тип класса без объединения, каждый нестатический член данных и каждый подобъект базового класса инициализируется нулем;
- если T является типом объединения, первый именованный член данных объекта инициализируется нулем;
- если T является типом массива, каждый элемент инициализируется нулем;
- если T - ссылочный тип, инициализация не выполняется.

Для инициализации по умолчанию объект типа T означает:
- если T не является типом класса POD (пункт 9), вызывается конструктор по умолчанию для T (и инициализация неверно сформирована, если T не имеет доступного конструктора по умолчанию);
- если T является типом массива, каждый элемент инициализируется по умолчанию;
- в противном случае объект инициализируется нулем.

Для инициализации значения объект типа T означает:
- если T является типом класса (пункт 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию);
- если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса T инициализируется значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- в противном случае объект инициализируется нулем

. Программа, которая вызывает инициализацию по умолчанию или инициализацию значения объекта ссылочного типа, плохо сформирована. Если T является типом с квалификацией cv, для этих определений инициализации нулем, инициализации по умолчанию и инициализации значения используется версия T без квалификации.

86
ответ дан 23 November 2019 в 06:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: