g ++ не включает файлы, которые он говорит, что включает в себя для C ++ 11?

Укороченная версия

Когда я компилирую даже простой код, используя особенность стандарта C ++ 11 ( std::stod функция), GCC 4.9.1 завершается с ошибкой:

example.cpp: In function 'int main()':
example.cpp:10:18: error: 'stod' is not a member of 'std'
double earth = std::stod (orbits,&sz);
^
example.cpp:11:17: error: 'stod' is not a member of 'std'
double moon = std::stod (orbits.substr(sz));
^

Какие?

Я использую команду g++ -std=c++11 example.cpp,

Это тестовый код (который прекрасно компилируется в других системах):

// stod example from http://www.cplusplus.com/reference/string/stod/
#include <iostream>   // std::cout
#include <string>     // std::string, std::stod

int main ()
{
std::string orbits ("365.24 29.53");
std::string::size_type sz;     // alias of size_t

double earth = std::stod (orbits,&sz);
double moon = std::stod (orbits.substr(sz));
std::cout << "The moon completes " << (earth/moon) << " orbits per Earth year.\n";
return 0;
}

подробности

Я использую версию GCC 4.9.1. Я скомпилировал себя на двух разных кластерах под управлением CentOS 6.5 (я использую систему модулей для вещей в моем домашнем каталоге, поскольку я не являюсь администратором).

Я буду называть их кластером 1 и кластер 2: кластер 1 где происходит сбой.

GCC были скомпилированы таким же образом и в то же время, и загружены с использованием идентичных файлов модулей (за исключением незначительного различия в базовом пути). Установки, насколько я могу легко проверить, идентичны (одни и те же файлы включения существуют в обоих кластерах и имеют одинаковое содержимое).

Выход из g++ -v одинаково на обоих кластерах (опять же, кроме пути установки):

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/andyras/bin/gcc-4.9.1/libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.9.1/configure --prefix=/home/andyras/bin/gcc-4.9.1 --enable-languages=c,c++,fortran
Thread model: posix
gcc version 4.9.1 (GCC)

g++ -v использование системы GCC дает одинаковый вывод в обоих кластерах, за исключением того, что в кластере 1 он говорит, что gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) и на кластере 2 говорит gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)

Я пытаюсь отладить с помощью g++ -std=c++11 -save-temps -MD example.cpp для получения дополнительной информации … это дает некоторые подсказки, но я не знаю, куда идти отсюда.

Промежуточный (.ii) в файлах кластера 1 отсутствуют некоторые строки, например (отрывок из diffв .ii файлы):

< # 277 "/opt/gcc-4.9.1/include/c++/4.9.1/cwchar" 3
---
> # 277 "/home/andyras/bin/gcc-4.9.1/include/c++/4.9.1/cwchar" 3
961,963c934,936
<   using std::wcstold;
<   using std::wcstoll;
<   using std::wcstoull;
---
>
>
>

Насколько я понимаю, GCC на обоих кластерах пытается включить файлы, такие как cwchar, но на кластере 1 вместо определяемых вещей есть пустые строки. На кластере 2 stod функция находится в промежуточном файле, но не в кластере 1.

Может ли это быть ошибка препроцессора?

Теперь, глядя на .d (зависимости) файлов, я также вижу конкретную разницу. В кластере есть несколько файлов 2 которые не перечислены в кластере 1. Вот список (я обработал содержимое .d файлы для учета различных базовых путей; // заменяет путь установки):

85a86,108
> //gcc-4.9.1/include/c++/4.9.1/ext/string_conversions.h
> //gcc-4.9.1/include/c++/4.9.1/cstdlib
> /usr/include/stdlib.h
> /usr/include/bits/waitflags.h
> /usr/include/bits/waitstatus.h
> /usr/include/sys/types.h
> /usr/include/sys/select.h
> /usr/include/bits/select.h
> /usr/include/bits/sigset.h
> /usr/include/sys/sysmacros.h
> /usr/include/alloca.h
> //gcc-4.9.1/include/c++/4.9.1/cstdio
> /usr/include/libio.h
> /usr/include/_G_config.h
> /usr/include/bits/stdio_lim.h
> /usr/include/bits/sys_errlist.h
> //gcc-4.9.1/include/c++/4.9.1/cerrno
> /usr/include/errno.h
> /usr/include/bits/errno.h
> /usr/include/linux/errno.h
> /usr/include/asm/errno.h
> /usr/include/asm-generic/errno.h
> /usr/include/asm-generic/errno-base.h

Мне было любопытно, если cpp искал включает в себя во всех не тех местах, но это кажется законным (cpp -v):

#include <...> search starts here:
/home/andyras/bin/gcc-4.9.1/include
/home/andyras/bin/gcc-4.9.1/include/c++/4.9.1/
/home/andyras/bin/gcc-4.9.1/include/c++/4.9.1/x86_64-unknown-linux-gnu/
/home/andyras/bin/gcc-4.9.1/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include
/usr/local/include
/home/andyras/bin/gcc-4.9.1/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include-fixed
/usr/include
End of search list.

Это была очень расстраивающая пара часов, пытающаяся отследить источник проблемы. Я мог бы, конечно, использовать что-то вроде atof(myString.c_str()) вместо std::stod, но мне интересно, если есть основная проблема, которая запутает будущие проекты, использующие другие биты C ++ 11.

Буду очень благодарен за любые подсказки или понимание.

8

Решение

Вы уже проделали всю необходимую работу для определения первопричины. Вы уже знаете ответ: вы опубликовали четкие различия между тем, как пользовательские установки gcc ведут себя на вашем «кластере 1» и «кластере 2», нерабочей и рабочей сборкой.

Итак, что-то явно отличается между этими двумя установками gcc; если один компилирует, связывает и запускает некоторый код, а другой задыхается от одного и того же куска кода. К сожалению, трудно точно определить, где все идет с рельсов. Создав сам gcc ранее, я могу сказать, что gcc — адски сложный и очень изменчивый пакет для установки. Например, после нескольких дней погони за таинственной ошибкой при связывании некоторого кода на C ++, я в итоге остановился на том, что gcc выбрал неправильную версию binutils в скрипте конфигурации gcc и внутренне отключил некоторые неясные функции, которые в конечном итоге проявились как ошибка соединения не gcc, а всего, что было создано с помощью gcc. Сам gcc был собран и установлен, без какой-либо жалобы, но он был сломан.

Таким образом, я нахожу совершенно неудивительным и вполне правдоподобным утверждение, что сам gcc был собран и установлен без явной проблемы, но он сломан и будет задыхаться от действительного кода таким образом.

Я полагаю, что ваша сборка gcc использует некорректный путь включения по умолчанию — он ищет заголовки в /usr/includeвместо собственного каталога установки. Это наиболее вероятный ответ, но это может быть что угодно.

4

Другие решения

Ну, у вас, очевидно, (как вы сами писали) два разных versoins gcc (один раз 4.4.7-3 и другой 4.4.7-4), и кажется, что они имеют (хотя и немного) различия в компиляции кода ,

Как я где-то читал, стандарт C ++ 11 еще не включен полностью во все компиляторы, так что, похоже, причина в одном кластере. Другой имеет (вы можете знать, почему) версию, в которую включено больше нового стандарта, и, поскольку вы хотите использовать именно эту функцию, я бы рекомендовал установить эту версию и на другом кластере.

1