Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

‘numeric_limits’ was not declared in this scope, no matching function for call to ‘max()’

I compiled this code at home on my mac w/ xcode and there was no provblem. I compile it at school with g++ on linux and I get these errors:

numeric_limits’ is not a member of std

expected primary-expression before ‘>’ token

no matching function for call to ‘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;
}

I'm guessing maybe I have to include an extra header. If I take away the std:: it just gives me a similar error:

numeric_limits was not declared in this scope

like image 444
Matt Munson Avatar asked Jan 25 '11 21:01

Matt Munson


2 Answers

You need to include the header file <limits>, which is where std::numeric_limits is defined. Your Mac compiler was helping you out by automatically including that header file; however, you should not rely on that behavior and explicitly include any header files you need.

like image 54
Adam Rosenfield Avatar answered Nov 07 '22 14:11

Adam Rosenfield


GCC 11 started to explicitly require including <limits>, <memory>, <utility>, <thread> according to https://www.gnu.org/software/gcc/gcc-11/porting_to.html#header-dep-changes

The same or similar story is with Clang 12 (or earlier, I don't know).

Since I meet this error (often) while using yarn (package manager for Node.js) and it overwrites all source files every time, I cannot add #include <limits> easily: I would need either to fork or spam cp /tmp/fixedBad.h /installdir/bad.h while compilation is ongoing.

Therefore my solution is to add to CXXFLAGS (not CFLAGS) this:

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

-include /usr/include/c++/11.1.0/limits (Arch Linux; same version but path differs from Debian/Ubuntu)

or elegantly: -include /usr/include/c++/11*/limits

Note that * works only when used by shell (bash, sh, zsh, etc.) or a makefile. In other words, gcc and clang don't pay attention to * in file paths, so beware if you use ninja build or directly pass arguments to gcc/clang from e.g. a C program.

I have this in /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"

Check echo $CXXFLAGS, and if changes aren't applied, restart shell or OS, or logout of the current tty, or switch to another tty, or just run in terminal:

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

or set -a; source /etc/environment; set +a;

I also tried adding to CXXFLAGS -include '<limits>' and -include '<limits.h>', but it says "No such file or directory"

Also I have another solution (very dirty):

Add this to /usr/include/stdint.h (or stdlib.h or some other popular file) before the last line (#endif):

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

Ubuntu 21.04's and Debian Buster's dpkg-query -S /usr/include/stdlib.h says it is owned by libc6-dev:amd64. Arch Linux's pacman -Qo /usr/include/stdlib.h says it is owned by glibc. So this hack will be overwritten when the package updates, don't forget.

like image 9
Arzet Ro Avatar answered Nov 07 '22 15:11

Arzet Ro