VC++: код работает в VS2010 и ломается в VS2013

Редактировать: в отличие от случая с вопросом, отмеченным в голосовании за закрытие, код нарушения здесь — это код CRT, не мой. Даже если у него есть проблема (а я почти уверен, что это не так), у меня нет возможности исправить ее источник.


У нас есть устаревший код отслеживания утечки памяти, который использует некоторые внутренние компоненты CRT (ничего особенного, по сути, _CrtMemBlockHeader, который имеет вид как-то задокументировано). При попытке перехода с VS2010 на VS2013 код, по-видимому, вызывает спорадические сбои сборки, и проблемную часть можно свести к следующему:

#include <windows.h>

#define _CRTBLD
#include <..\crt\src\dbgint.h>

#include <fstream>
void Func()
{
    std::ofstream myfile;
    myfile << 8;
}

Т. е. одни только эти 10 строк отлично строятся в VS2010, а в VS2013 дают:

c:\program files (x86)\microsoft visual studio 12.0\vc\include\xlocnum(1105): ошибка C2491: 'std::numpunct‹_Elem>::id': определение члена статических данных dllimport не разрешено

Я подозреваю, что сообщение об ошибке неточно — действительно есть несколько потенциальных определений id, ни одно из них в строке 1105. Также имеется значительное количество предупреждений:

1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xlocnum(1105): warning C4273: 'id' : inconsistent dll linkage
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xlocnum(80) : see previous definition of 'public: static std::locale::id std::numpunct<char>::id'
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xlocnum(80) : while compiling class template static data member 'std::locale::id std::numpunct<_Elem>::id'
1>          with
1>          [
1>              _Elem=char
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xlocnum(1185) : see reference to function template instantiation 'const _Facet &std::use_facet<std::numpunct<_Elem>>(const std::locale &)' being compiled
1>          with
1>          [
1>              _Facet=std::numpunct<char>
1>  ,            _Elem=char
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xlocnum(1179) : while compiling class template member function 'std::ostreambuf_iterator<char,std::char_traits<char>> std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char>>>::do_put(_OutIt,std::ios_base &,_Elem,std::_Bool) const'
1>          with
1>          [
1>              _OutIt=std::ostreambuf_iterator<char,std::char_traits<char>>
1>  ,            _Elem=char
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(306) : see reference to class template instantiation 'std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char>>>' being compiled
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(292) : while compiling class template member function 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(int)'
1>          c:\users\ofek\documents\visual studio 2013\projects\testcamsys2013\testcamsys2013\source.cpp(10) : see reference to function template instantiation 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(int)' being compiled
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\fstream(921) : see reference to class template instantiation 'std::basic_ostream<char,std::char_traits<char>>' being compiled
1>          c:\users\ofek\documents\visual studio 2013\projects\testcamsys2013\testcamsys2013\source.cpp(9) : see reference to class template instantiation 'std::basic_ofstream<char,std::char_traits<char>>' being compiled

Сейчас я вставляю определения _CrtMemBlockHeader и некоторые макросы вокруг него непосредственно в свой код. Но все же - может кто видел, что сломалось?

Я понимаю, что он поддерживается не полностью, но можно надеяться: есть ли более надежный способ использования _CrtMemBlockHeader?


person Ofek Shilon    schedule 07.10.2014    source источник
comment
Я был здесь раньше... убедитесь, что у вас есть ВСЕ заголовки #includeed. VS2010 автоматически #include заголовки, но VS2013 этого не делает.   -  person AStopher    schedule 07.10.2014
comment
(1) VS2010/2013 использует идентичный аппарат для разрешения включений (с разными папками заголовков CRT), (2) сама ошибка не относится к семейству «неопределенный символ»/«описатель отсутствующего типа» и т. д., поэтому - это очень вряд ли проблема с включением заголовка.   -  person Ofek Shilon    schedule 07.10.2014
comment
Попробуйте: stackoverflow.com/questions/8401359/   -  person AStopher    schedule 07.10.2014
comment
Я не голосовал за закрытие, прошу не оскорблять.   -  person AStopher    schedule 07.10.2014
comment
Прошу прощения, спасибо, что нашли время, чтобы попытаться помочь. Эти рефлекторные отрицательные / близкие голоса меня действительно раздражают.   -  person Ofek Shilon    schedule 07.10.2014


Ответы (1)


Глядя на эту ошибку в моей системе, кажется, что она связана только с заголовками #define _CRTBLD и fstream. Включенный dbgint.h не имеет значения (вы можете закомментировать этот #include и все равно получить ту же ошибку.

Итак, похоже, проблема в заголовке fstream. Изменение порядка включения убирает ошибки компиляции:

#include <windows.h>
#include <fstream>

#define _CRTBLD
#include <..\crt\src\dbgint.h>

Возможно, это помогает?

person Roger Rowland    schedule 08.10.2014
comment
Я только что увидел, что мой первоначальный комментарий не появился. Спасибо, это более или менее решение, которое я в конечном итоге использовал. Я не менял порядок включения, вместо этого #undef'd _CRTBLD сразу после включения dbgint. - person Ofek Shilon; 05.11.2014