sba1 / adtools

Experimental GNU toolchain for AmigaOS
32 stars 18 forks source link

error: ‘stoi’ is not a member of ‘std’ #57

Open kas1e opened 5 years ago

kas1e commented 5 years ago

While trying to compile some programms, found 2 times error about ‘stoi’ is not a member of ‘std’.

There is simple test case:

#include <thread> #include <future>

#include <cstdio> #include <unistd.h>

enum MapParameterIndices : int { LEVELPARAM_CHANCE_SECRET, LEVELPARAM_CHANCE_DARKNESS, LEVELPARAM_CHANCE_MINOTAUR };

std::string parameterStr = "";

std::tuple<int, int, int> mapParameters = std::make_tuple(-1, -1, -1);

int main() { std::get<LEVELPARAM_CHANCE_SECRET>(mapParameters) = std::stoi(parameterStr); }

On cygwin with gcc 7.3.0, it compiles fine just with "g++ test.cpp". On amigaos4 , with 8.2.0 gcc, i tried to compile it like this : ppc-amigaos-g++ -athread=native -std=c++11 test1.cpp , and have:

test1.cpp: In function ‘int main()’: test1.cpp:24:59: error: ‘stoi’ is not a member of ‘std’ std::get<LEVELPARAM_CHANCE_SECRET>(mapParameters) = std::stoi(parameterStr);

But as i know It should be there with C++11 and more.

kas1e commented 5 years ago

Diggin into the google for this one too, and found that patch for MinGW i mention in the issue #58, include "stoi" as well: http://tehsausage.com/mingw-to-string

This patch enables the following list of C++11 functions and templates in the std namespace: stoi, stol, stoul, stoll, stof, stod, stold, to_string, to_wstring

Maybe it will be any of help for us ?

raziel- commented 5 years ago

This bit me today too, would be nice to have it supported

btw: It doesn't matter if i use -std=c++11 or -std=gnu++11, i get the same error

kas1e commented 5 years ago

Found today that most of those kind of functions give the same "not a member of std" , for example those ones too:

stoi stod stof stoul stol

What interesting, is that if we check gcc includes like:

include\c++\8.2.0\bits\basic_string.h or include\c++\8.2.0\ext\vstring.h we can find there something like:

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if _GLIBCXX_USE_C99_STDLIB
  // 21.4 Numeric Conversions [string.conversions].
  inline int
  stoi(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
                    __idx, __base); }

  inline long
  stol(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
                 __idx, __base); }

  inline unsigned long
  stoul(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
                 __idx, __base); }

  inline long long
  stoll(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
                 __idx, __base); }

  inline unsigned long long
  stoull(const __vstring& __str, std::size_t* __idx, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
                 __idx, __base); }

  // NB: strtof vs strtod.
  inline float
  stof(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }

  inline double
  stod(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }

  inline long double
  stold(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
#endif // _GLIBCXX_USE_C99_STDLIB 

So , kind of should works when we use _GLIBCXX_USE_C99_STDLIB which we can se in the include/c++/8.2.0/bits/c++config.h. But it didn't sadly.

In other words, it seems that those "not a member" errors not errors of newlib, but errors of includes provided with gcc on our side.

arfcarl commented 4 years ago

I have the same problem using gcc 8.3.0 with std::stoi and std:stod.

arfcarl commented 4 years ago

Found today that most of those kind of functions give the same "not a member of std" , for example those ones too:

stoi stod stof stoul stol

What interesting, is that if we check gcc includes like:

include\c++\8.2.0\bits\basic_string.h or include\c++\8.2.0\ext\vstring.h we can find there something like:

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if _GLIBCXX_USE_C99_STDLIB
  // 21.4 Numeric Conversions [string.conversions].
  inline int
  stoi(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
                  __idx, __base); }

  inline long
  stol(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
               __idx, __base); }

  inline unsigned long
  stoul(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
               __idx, __base); }

  inline long long
  stoll(const __vstring& __str, std::size_t* __idx = 0,   int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
               __idx, __base); }

  inline unsigned long long
  stoull(const __vstring& __str, std::size_t* __idx, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
               __idx, __base); }

  // NB: strtof vs strtod.
  inline float
  stof(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }

  inline double
  stod(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }

  inline long double
  stold(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
#endif // _GLIBCXX_USE_C99_STDLIB 

So , kind of should works when we use _GLIBCXX_USE_C99_STDLIB which we can se in the include/c++/8.2.0/bits/c++config.h. But it didn't sadly.

In other words, it seems that those "not a member" errors not errors of newlib, but errors of includes provided with gcc on our side.

Actually, your suggestion on adding #define _GLIBCXX11_USE_C99_STDLIB 1 to include/c++/8.3.0/bits/c++config.h DID infact solve my stoi/stoid issue. Thanks.

doothez commented 4 years ago

If you are using gcc 5.2.0, put below line in CMakeList.txt target_compile_options(${COMPONENT_TARGET} PUBLIC -D_GLIBCXX_USE_C99 -D_GLIBCXX_USE_WCHAR_T )

ksdhans commented 4 years ago

It would be great if this could be fixed. As with issue #58, I'd submit a pull request if I knew how to generate the patches.

kas1e commented 3 years ago

from newlib's side everything about "not a member of std::" was fixed in the new beta of newlib 53.69 and adtools recompiled with new newlib's headers.