2016-10-20 2 views
4

В соответствии с С ++ 11 спецификации:статической инициализации порядка облом, iostream и C++ 11

Результаты включая <iostream> в единице перевода должно быть, как если бы <iostream> определен экземпляр ios_base::Init со статическим хранения продолжительность. Кроме того, вся программа должна вести себя так, как будто там было по крайней мере один экземпляр ios_base::Init с длительностью статического хранения

Это означает, что, если мой код выглядит следующим образом:

// A.cpp 
#include <iostream> 
using namespace std; 
unsigned long foo() { 
    cerr << "bar"; 
    return 42; 
} 

и

// B.cpp 

using namespace std; 
extern unsigned long foo(); 

namespace { 
unsigned long test() { 
    int id = foo(); 
    return id; 
} 

unsigned long id = test(); 
} 


int main() { 
    return 0; 
} 

тогда я должен быть безопасно звонить cerr без риска статического фиаско инициализации.

К сожалению, этот код segfaults ... Почему? Я не думаю, что gcc 6.2.1 решил игнорировать спецификацию C++ 11, и я включил <iostream> в A.cpp. Согласно спецификации, этого должно быть достаточно.

+6

Пожалуйста, укажите точный код, который точно соответствует требованиям. – bmargulies

+0

Выполнено (15 символов) – marmistrz

+0

Это даже не компилируется. –

ответ

6

Полная цитата из пункта включает в себя:

объекты построены и объединения создаются на некоторое время до или в течение первого времени объект класса ios_base :: Init построен, и в любом случае перед началом основного тела исполнение. 293)

И сноске

293) Если это возможно для них, чтобы сделать так, реализации рекомендуется инициализировать объекты раньше, чем требуется.

Таким образом, гарантия, что iostreams будет работать на последнем при входе в главный. Нет строгого требования, чтобы они работали раньше, если единица перевода не включает <iostream>.

Вы нашли способ обойти это!

При вызове foo() из B.cpp экземпляр ios_base::Init, включенный в A.cpp, может быть инициализирован или не установлен.

+0

Итак, это сработало бы, если бы я явно включил '' в 'B.cpp'? – marmistrz

+2

Да, должно. Но это странное обходное решение. –

 Смежные вопросы

  • Нет связанных вопросов^_^