'numeric_limits' не было объявлено в этой области, нет соответствующей функции для вызова 'max()'

Я скомпилировал этот код дома на своем Mac с xcode, и никаких проблем не было. Я компилирую это в школе с g++ на linux, и я получаю эти ошибки:

: 'numeric_limits' не является членом std
: ожидаемое первичное выражение до токена '>'
: нет подходящей функции для вызова max()

#include <iostream>
#include <cstdlib>

using namespace std;

int GetIntegerInput(int lower, int upper)
{
    int integer = -1;
    do
    {    
        cin >> integer;
        cin.clear();
        cin.ignore(std::numeric_limits<streamsize>::max(), '\n');  //errors here
    }while (integer < lower || integer > upper);

    return integer;    
} 

Возможно, мне нужно добавить дополнительный заголовок. Если я уберу std::, это просто выдаст мне похожую ошибку

'numeric_limits' не был объявлен в этой области

2 ответа

Решение

Вам нужно включить заголовочный файл <limits>где std::numeric_limits определено. Ваш компилятор Mac помог вам, автоматически включив этот заголовочный файл; однако вы не должны полагаться на это поведение и явно включать любые заголовочные файлы, которые вам нужны.

GCC 11 начал явно требовать включения <limits>, <memory>, <utility>, <thread>согласно https://www.gnu.org/software/gcc/gcc-11/porting_to.html#header-dep-changes

Такая же или похожая история с Clang 12 (или раньше, я не знаю).

Поскольку я встречаю эту ошибку (часто) при использовании yarn (менеджер пакетов для Node.js), и он каждый раз перезаписывает все исходные файлы, я не могу добавить #include <limits> легко: мне понадобится либо форк, либо спам cp /tmp/fixedBad.h /installdir/bad.h пока идет компиляция.

Поэтому мое решение - добавить в CXXFLAGS (не CFLAGS) следующее:

-include /usr/include/c++/11/limits (Ubuntu 21.04, gcc 11.1.0)

-include /usr/include/c++/11.1.0/limits (Arch Linux; та же версия, но путь отличается от Debian / Ubuntu)

или элегантно: -include /usr/include/c++/11*/limits ( * работает из-за shell / make, а не из-за gcc / clang, поэтому будьте осторожны, если вы напрямую передаете аргументы в gcc / clang, например, из программы C)

У меня это в /etc/environment

      #CPPFLAGS="-D_FORTIFY_SOURCE=2 -DNDEBUG"
CPPFLAGS="-D_FORTIFY_SOURCE=2"
CFLAGS="-g -pipe -march=native -mtune=native -Ofast -pipe -ftree-vectorize -fstack-protector-strong"
CXXFLAGS="-g -pipe -march=native -mtune=native -Ofast -pipe -ftree-vectorize -fstack-protector-strong -include /usr/include/c++/11*/limits"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"
RUSTFLAGS="-C target-cpu=native -C opt-level=2"

Проверять echo $CXXFLAGS, и если изменения не применяются, перезапустите оболочку или ОС, или выйдите из текущего tty, или переключитесь на другой tty, или просто запустите в терминале:

      export CXXFLAGS="-g -pipe -march=native -mtune=native -Ofast -pipe -ftree-vectorize -fstack-protector-strong -include /usr/include/c++/11*/limits"

или же set -a; source /etc/environment; set +a;

Я также пробовал добавить в CXXFLAGS -include '<limits>' а также -include '<limits.h>', но написано: "Нет такого файла или каталога"

Также у меня есть другое решение (очень грязное):

Добавьте это в /usr/include/stdint.h (или же stdlib.h или какой-нибудь другой популярный файл) перед последней строкой ( #endif):

      #ifdef __cplusplus
extern "C++" {
       #include <limits>
}
#endif

Ubuntu 21.04 и Debian Buster's dpkg-query -S /usr/include/stdlib.h говорит, что он принадлежит libc6-dev:amd64. Arch Linux's pacman -Qo /usr/include/stdlib.h говорит, что он принадлежит glibc. Так что этот хак будет перезаписан при обновлении пакета, не забывайте.

Другие вопросы по тегам