Почему я получаю эти предупреждения в Visual C ++ 2008 при построении структуры? - PullRequest
6 голосов
/ 22 августа 2011

У меня есть этот код

typedef struct
{
    const char* fooString;
    const bool  fooBool;
}fooStruct;

И этот инициализатор:

static const fooStruct foo[] =
{
    {"file1", true},
    {"file2", false},
    ....
};

С этим кодом у меня есть 3 предупреждения в VS2008:

error C2220: warning treated as error - no 'object' file generated  
warning C4510: '<unnamed-tag>' : default constructor could not be generated
warning C4512: '<unnamed-tag>' : assignment operator could not be generated
warning C4610: struct '<unnamed-tag>' can never be instantiated - user defined constructor required 

Ответы [ 3 ]

11 голосов
/ 22 августа 2011

Это именно то, что говорит компилятор: он не может сгенерировать конструктор по умолчанию или оператор присваивания для вашей структуры, потому что в нем есть const член (const bool fooBool). Элементы структуры, которые const или являются ссылками, не могут быть инициализированы по умолчанию, поэтому они должны быть явно инициализированы в пользовательском конструкторе или операторе присваивания.

Одним из решений является написание собственного конструктора по умолчанию и оператора присваивания (и в соответствии с правилом из трех , вы также должны написать конструктор копирования; деструктор не является строго необходимым, но это хорошая практика ). Альтернативное, более простое решение - просто сделать fooBool non- const. Затем компилятор с радостью сгенерирует для вас конструктор по умолчанию и оператор присваивания.

Поскольку вы уже создаете массив из const их экземпляров с помощью static const fooStruct foo[] = ..., дополнительные const для fooBool не имеют смысла.

8 голосов
/ 22 августа 2011

Предупреждение C4610 неверно. Это известная ошибка в Visual C ++. См. Ошибку Microsoft Connect «Неправильная выдача C4610.»

Адам Розенфилд объясняет , почему появляются два других предупреждения (C4510 и C4512).

0 голосов
/ 06 января 2012

Также, если вы выполняете частичную инициализацию, MSVC2008 будет выдавать ошибки (как и MSVC2010), что является некорректным поведением, как определено в C ++ 03 и C ++ 11.Я написал больше об этом в другой теме о переполнении стека, которую вы можете прочитать здесь

// Partial initialization, leaving it to the compiler
// to do aggregate value-initialization
fooStruct foo ={"file1", /*missing true/false, compiler should set false*/ };

MSVC выдаст ошибку в этом коде вместе с упомянутыми вами предупреждениями.

...