Это отредактированный вопрос, основанный на первых ответах. Другие указали мне, что код, который я должен был признать недействительным, был отлично в С++ 11. Тем не менее поведение gcc
отличается в зависимости от того, что не должно быть связано.
Существует файл, содержащий
std::string logFilePath;
/*...*/
std::ofstream logfile(logFilePath, std::ofstream::trunc);
эта строка компилируется и связывается в Windows (MSVC2010
) и под Linux (G++4.4
) с установкой -std=c++0x
. Когда я даю -O0
вариант, сцепление бреши и дает ошибку:
undefined reference to 'std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'
Вопрос в том, почему это происходит именно так? Кажется, это ошибка в gcc
но любая дополнительная информация была бы замечательной.
Существует старая тема, касающаяся одной и той же проблемы, которая привела меня к -Ox
виновнику, но нет объяснений, только подсказка для решения.
Вот минимальный пример:
#include <string>
#include <fstream>
#include <iostream>
int main (int, char**)
{
std::string name = "name";
std::ofstream stream(name, std::ofstream::trunc);
return 0;
}
а потом:
$ /usr/bin/g++44 -std=c++0x main.cpp -Wall -O1
$ /usr/bin/g++44 -std=c++0x main.cpp -Wall -O0
/tmp/ccBjIuWi.o: In function 'main':
main.cpp:(.text+0x80): undefined reference to 'std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'
collect2: ld returned 1 exit status
первая строка компилируется штрафом и дает ожидаемое поведение без учета уровня уровня оптимизации, за исключением -O0
, то есть любой из 1
, 2
, 3
, s
будет делать.
Вот еще дополнительная информация относительно системы:
$ /usr/bin/g++44 -v
Using built-in specs.
Target: x86_64-redhat-linux6E
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --disable-gnu-unique-object --with-as=/usr/libexec/binutils220/as --enable-languages=c,c++,fortran --disable-libgcj --with-mpfr=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/mpfr-install/ --with-ppl=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/ppl-install --with-cloog=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/cloog-install --with-tune=generic --with-arch_32=i586 --build=x86_64-redhat-linux6E
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-1) (GCC)
$ cat /etc/redhat-release
CentOS release 5.9 (Final)
Конструктор с std :: basic_string был добавлен в C++ Standard 2011. До этого этого конструктора не было. Вместо него использовался конструктор с параметром type const char *.
Это связано с тем, что код не является недопустимым в С++ 11. Конструктор, принимающий std::string
качестве первого аргумента, был добавлен С++ 11. Флаг std=c++0x
сообщает g++ компилировать в режиме С++ 11 (или какой-либо подмножество будущего С++ 11, который он поддерживал в вашей версии)
В С++ 03 вам необходимо передать const char*
:
std::ofstream stream(name.c_str(), std::ofstream::trunc);
Что касается зависимости от уровня оптимизации, это, скорее всего, либо проблема с вашей установкой, либо подлинная ошибка в этой конкретной версии g++. К сожалению, я не в состоянии воспроизвести его.
std::string
, теперь это не выглядит так загадочно.