Сегодня меня укусила ошибка.
Вопрос для юристов C ++
Рассмотрим следующий источник:
struct MyPod
{
short m_short ;
const char * const m_string ;
} ;
MyPod myArrayOfPod[] = { { 1, "Hello" } } ;
int main(int argc, char * argv[])
{
return 0 ;
}
Обратите внимание, что все значения известны во время компиляции, и что MyPod является POD.
Итак, должен ли myArrayOfPod быть инициализирован во время компиляции, или компилятор сгенерирует какой-то конструктор MyPod по умолчанию?
Подробности, включая автономный источник
Следующий источник, который воспроизводит ошибку, можно скопировать / вставить в файл main.cpp:
#include <iostream>
// The point of SomeGlobalObject is for its
// constructor to be launched before the main
// ...
struct SomeGlobalObject
{
SomeGlobalObject() ;
} ;
// ...
// Which explains the global object
SomeGlobalObject oSomeGlobalObject ;
// A POD... I was hoping it would be constructed at
// compile time when using an argument list
struct MyPod
{
short m_short ;
const char * const m_string ;
} ;
// declaration/Initialization of a MyPod array
MyPod myArrayOfPod[] =
{ { 1, "Hello" }, { 2, "World" }, { 3, " !" } } ;
// declaration/Initialization of an array of array of void *
void * myArrayOfVoid[][2] =
{ { (void *)1, "Hello" }, { (void *)2, "World" }, { (void *)3, " !" } } ;
// constructor of the global object... Launched BEFORE main
SomeGlobalObject::SomeGlobalObject()
{
// The two values should be "1"
std::cout << "myArrayOfPod[0].m_short : " << myArrayOfPod[0].m_short << std::endl ;
std::cout << "myArrayOfVoid[0][0] : " << myArrayOfVoid[0][0] << std::endl ;
}
// main... What else ?
int main(int argc, char* argv[])
{
return 0 ;
}
MyPod, будучи POD, я верил, что конструкторов не будет. Только инициализация во время компиляции.
Таким образом, глобальный объект SomeGlobalObject
не будет иметь проблем с использованием глобального массива POD при его создании.
Но в Visual C ++ 2008 в режиме отладки при выполнении myArrayOfPod
не инициализируется должным образом (все его значения обнуляются), даже если myArrayOfVoid
правильно инициализирован.
Итак, мои вопросы: Разве компиляторы C ++ не должны инициализировать глобальные POD (включая структуры POD) во время компиляции?
Displaimer
Обратите внимание, что я знаю, что глобальные переменные являются злом, и я знаю, что нельзя быть уверенным в порядке создания глобальных переменных, объявленных в разных единицах компиляции, но это не по теме: вопрос о глобальных Инициализация POD.
Редактировать
Я скопировал / вставил этот код в свою Ubuntu, и, что касается g ++ 4.4.3, эти два массива правильно инициализированы как в режиме отладки, так и в режиме выпуска.
О поведении сообщили в Microsoft и ожидают подтверждения:
https://connect.microsoft.com/VisualStudio/feedback/details/564844/pod-struct-global-object-initialization-uses-constructor
Редактировать 2
Visual C ++ QA ответил на сообщение об ошибке, цитируя стандарт (по крайней мере, n3092 ). Что касается их поведения, то поведение, наблюдаемое в Visual C ++, соответствует стандарту.
И несмотря на мои "чувства", это все еще ошибка, я должен признать тот факт, что они знают стандарт бесконечно больше, чем я (хотя бы потому, что я использую язык , когда они пишут компилятор для языка ), и, таким образом, принять свой ответ.
Итак, я сделаю домашнее задание, то есть прочитаю n3092 от начала до конца (Тысяча страниц подобных юристам заявлений ... Это моя удача ...) : В этом документе используется много четко определенных слов, и если я не знаю точного значения каждого слова, я не смогу процитировать какой-то параграф n3092 , чтобы поддержать мою точку зрения ...
Благодарю MSN и AndreyT за ответы.