23

My code:

#include <iostream>
#include <string>

int main()
{
    std::string test = "45";
    int myint = std::stoi(test);
    std::cout << myint << '\n';
}

Gives me the compile error:

error: 'stoi' is not a member of 'std'
     int myint = std::stoi(test);
                 ^

However, according to here, this code should compile fine. I am using the line set(CMAKE_CXX_FLAGS "-std=c++11 -O3") in my CMakeLists.txt file.

Why is it not compiling?


Update: I am using gcc, and running gcc --version prints out:

gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
Community
  • 1
  • 1
Karnivaurus
  • 22,823
  • 57
  • 147
  • 247
  • You didn't specify what compiler version you are using. – Captain Obvlious Jun 26 '16 at 00:36
  • Look at this thread http://www.cplusplus.com/forum/beginner/120836/ – jonathanGB Jun 26 '16 at 00:37
  • @CaptainObvlious, I am using gcc version 5.2.1 – Karnivaurus Jun 26 '16 at 00:45
  • Compiles without issues with gcc 6.1.1 on Fedora 24. – Sam Varshavchik Jun 26 '16 at 00:51
  • unable to reproduce using g++ 5.2.1 on Ubuntu – 2785528 Jun 26 '16 at 01:10
  • 1
    @Karnivaurus First of all, `gcc` is the C compiler, not the C++ compiler. `g++` is the C++ compiler, so you should make sure that you are compiling with the correct compiler. – CinchBlue Jun 26 '16 at 01:10
  • @DOUGLASO.MOEN Really? [This doesn't appear to work on StackedCrooked.](http://coliru.stacked-crooked.com/a/a30fa5d98b8ccfcc) – CinchBlue Jun 26 '16 at 01:13
  • @VermillionAzure: `gcc` will compile C++ fine based on file extension, but it doesn't take care of linking the standard library, which the `g++` wrapper does. – Nick Matteo Jun 26 '16 at 01:16
  • Also, I don't know if the compiler version is a problem: [this compiles correctly on 5.2.0 with Godbolt](http://gcc.godbolt.org/#compilers:!((compiler:g520,options:'-std%3Dc%2B%2B11+-O3',source:'%23include+%3Ciostream%3E%0A%23include+%3Cstring%3E%0A%0Aint+main()%0A%7B%0A++++std::string+test+%3D+%2245%22%3B%0A++++int+myint+%3D+std::stoi(test)%3B%0A++++std::cout+%3C%3C+myint+%3C%3C+!'%5Cn!'%3B%0A%7D')),filterAsm:(commentOnly:!t,directives:!t,labels:!t),version:3) – CinchBlue Jun 26 '16 at 01:16
  • VTC. The problem can't be reproduced, and I find it very hard to believe we have full details here. – SergeyA Jun 26 '16 at 02:14

5 Answers5

19

In libstdc++, the definitions of stoi, stol, etc., as well as the to_string functions, are guarded by the condition

#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
     && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))

I have had this fail on one platform before (namely Termux on Android), resulting in to_string not being available even with g++ 6.1 and the C++14 standard. In that case, I just did

#define _GLIBCXX_USE_C99 1

before including anything, and voilà, suddenly the functions existed. (You should put this first, or even on the command line, rather than just before including <string>, because another header may include <string> first, and then its include guards will keep it from ever seeing your macro.)

I did not investigate why this macro wasn't set in the first place. Obviously this is a cause for concern if you want your code to actually work (in my case I didn't particularly, but FWIW there were no problems.)

You should check if _GLIBCXX_USE_C99 is not defined, or if _GLIBCXX_HAVE_BROKEN_VSWPRINTF is defined (which may be the case on MinGW?)

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Nick Matteo
  • 4,453
  • 1
  • 24
  • 35
  • libstdc++ umm the OP issue is certainly related to `gcc`. He has to use `g++`. Because Rup(a SO user) says gcc will select the correct back-end compiler based on file extension (i.e. will compile a .c as C and a .cc as C++) and links binaries against just the standard C and GCC helper libraries by default regardless of input languages; g++ will also select the correct back-end based on extension except that I think it compiles all C source as C++ instead (i.e. it compiles both .c and .cc as C++) and it includes libstdc++ in its link step regardless of input languages. – Soner from The Ottoman Empire Jun 26 '16 at 01:18
  • 1
    @snr: OP is not getting a linker error, but a compiler error, saying that the function was not declared. This is not caused by using the `gcc` command versus the `g++` command. Referring to g++ as GCC is perfectly correct, by the way. – Nick Matteo Jun 26 '16 at 01:22
  • what about `libstdc++`? – Soner from The Ottoman Empire Jun 26 '16 at 01:23
  • isn't it a kind of link? – Soner from The Ottoman Empire Jun 26 '16 at 01:26
  • @snr: Yes, it needs to be linked in. If it wasn't being linked correctly, _nothing_ from `std` would work; it wouldn't be reflected by the lack of one particular function, which could be "fixed" by using `std::atoi` instead. Also, the OP got a _compiler error_: this cannot have anything to do with linking. It means that the compiler didn't see the desired definition in the included headers, even though it should have. Linking happens last: if the requisite parts of libstdc++ weren't linked in, it would cause lots of undefined references, not compiler errors. – Nick Matteo Jun 26 '16 at 01:34
  • Do not manually set those defines. Use the proper compiler flags. The issue is the C++ standard (`__cplusplus >= 201103L`). You should make sure you are compiling with `std=c++11`. Rather than set `_GLIBCXX_USE_C99` (which sets the C standard version to bring in those symbols), you should be using the proper C++ version. OP mentioned that they had set `set(CMAKE_CXX_FLAGS "-std=c++11 -O3")`, which means the only possible problem is that either these flags didn't actually make it into the compiler command, or the std was reset later on the command line to something else. – Taywee Jun 26 '16 at 17:39
9

std::stoi is a C++11 function. You have to use the -std=c++11 to enable it in both g++ and clang++. This is the actual issue, not a linking error or a specific preprocessor define.

 $ cat test.cxx
#include <iostream>
#include <string>

int main()
{
    std::string test = "45";
    int myint = std::stoi(test);
    std::cout << myint << '\n';
}
 $ g++ -otest test.cxx
test.cxx: In Funktion »int main()«:
test.cxx:7:17: Fehler: »stoi« ist kein Element von »std«
     int myint = std::stoi(test);
                 ^
 $ g++ -otest test.cxx -std=c++11
 $ ./test
45
 $

edit: I just saw that you used c++11. Are you sure that's making it into your compile options? Check the generated makefile and watch the executed commands to be certain.

Taywee
  • 1,313
  • 11
  • 17
  • Nope, this is platform-dependent indeed (my platform is OpenWRT for MIPS). Kundor had made a great point about _GLIBCXX_USE_C99. – ogurets Jun 28 '18 at 15:13
3

Your version seems up to date, so there shouldn't be an issue. I think it may be related to gcc. Try g++ instead.(Most likely automatically linking issue. If you just run gcc on a C++ file, it will not 'just work' like g++ does. That's because it won't automatically link to the C++ std library, etc.). My second advise is try std::atoi.

@ I have fixed the issue. std::stoi uses libstdc++. It is about The GNU Standard C++ Library. In gcc you have to link adding -lstdc++. However, in g++, libstdc++ is linked automatically. using gcc and using g++

Pay attention how it is compiled

using g++: g++ -std=c++11 -O3 -Wall -pedantic main.cpp && ./a.out

using gcc: gcc -std=c++11 -O3 -Wall -pedantic -lstdc++ main.cpp && ./a.out

I think you should set flag like set(CMAKE_EXE_LINKER_FLAGS "-libgcc -lstdc++") (Not tested)

#include <cstdlib>

int myInt = std::atoi(test.c_str());
  • Thanks -- using `std::atoi` worked for me. Although I'm still not sure of the underlying problem with `std::stoi`... – Karnivaurus Jun 26 '16 at 01:18
  • 1
    @Karnivaurus The issue has to do with linking in the C++ standard library. With the `gcc` command, you must do it manually with something like `-lstdc++` but `g++` will link in this for you automatically. [Example](http://coliru.stacked-crooked.com/a/805d20d69f46d8d8) – CinchBlue Jun 26 '16 at 01:20
  • @Vermilion: if it worked fine with atoi, then it's not a linking error. As the error said in the first place, it's that the functions were not declared in the header, because they were removed by the preprocessor. This has nothing to do with linking or `gcc` vs `g++` commands. – Nick Matteo Jun 26 '16 at 01:27
  • I really like to see someone's incomplete or incorrect information. Look through with paying special attention to the links: [with gcc](http://coliru.stacked-crooked.com/a/43d03f2a9ee33f9d) and [with g++](http://coliru.stacked-crooked.com/a/d018ca9cd2dc5e26) @Kundor – Soner from The Ottoman Empire Jun 26 '16 at 01:36
  • @snr: Yes, that perfectly demonstrates all the reasons I gave above why your explanation cannot be correct. As I said: with `gcc`, _nothing_ works: it's not the case that just one function `stoi` gives problems, and changing it to `atoi` will make it magically work. NOTHING WORKS. And, the errors are all LINKER ERRORS. There is not a single compiler error, because the compiler knows nothing about linking. When the compiler says that something is not found, that means that it wasn't in the text fed to the compiler. This is NOT THE SAME as the linker not finding the reference. – Nick Matteo Jun 26 '16 at 01:41
  • This is incorrect answer, even if using atoi solves OP issue. – SergeyA Jun 26 '16 at 02:13
  • okay if the issue is not related to linking, then please explain your votedown and the reason @SergeyA – Soner from The Ottoman Empire Jun 26 '16 at 02:18
  • @snr, it was explained multiple times already - OP has a compile issue, not link issue. Linking issue wouldn't be fixed by `std::atoi`. – SergeyA Jun 26 '16 at 02:21
  • I said it is related to gcc and g++. So it is implicitly about linking. [gcc](http://coliru.stacked-crooked.com/a/43d03f2a9ee33f9d) and [g++](http://coliru.stacked-crooked.com/a/d018ca9cd2dc5e26) @SergeyA – Soner from The Ottoman Empire Jun 26 '16 at 02:24
  • @snr, no, it is not about linking, and this is why your answer is incorrect. Your own link shows that - error is not the same, and atoi doesn't fix it. – SergeyA Jun 26 '16 at 02:25
  • @snr This is clearly not related to linking, as that is a compiler error. It's an incorrect answer. If it was related to linking you could use the -c flag and you wouldn't see it. – Taywee Jun 26 '16 at 17:36
0

If you are using Cmake to compile, add line:

"add_definitions(-std=c++11)"

after find_package command.

Zhongyi
  • 381
  • 4
  • 5
0

Use 'set(CMAKE_CXX_STANDARD 11)' for Cmake