Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use std::stoul and std::stoull in Android?

Tags:

C++11 has two new string conversion functions into unsigned long and long long: std::stoul() and std::stoll().

The recent Android NDK r9 introduces Clang 3.3 compiler which is said to be C++11 feature complete. There are prototypes for these functions deep inside NDK, however I cannot use them.

What do I need to do to use them?

P.S. I already do LOCAL_CPPFLAGS += -std=c++11

like image 639
Sergey K. Avatar asked Jul 30 '13 15:07

Sergey K.


2 Answers

The reason why you cannot use the functions is quite deep rooted, and unfortunately currently unsolvable.

Looking into the libs/armeabi-v7a/include/bits/c++config.h file in the gnu stdlibc++ folder, you'll see this:

... /* Define if C99 functions or macros from <wchar.h>, <math.h>, <complex.h>,    <stdio.h>, and <stdlib.h> can be used or exposed. */ /* #undef _GLIBCXX_USE_C99 */ ... 

The above, in conjunction with the following snippet from bits/basic_string.h spells bad news:

... #if (defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99) \      && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))  /* The definitions of Numeric Conversions [string.conversions] */ #endif ... 

Thus, these functions are unusable in the NDK.

Root Cause: The root cause seems to be that the C99 functionality usage has been disabled in the GNU stdlibc++ on the armeabi-v7a platform due to the fact the the Bionic libc does not support complex math (the standard C library on Android is Bionic).

Possible Fix (untested): Explore CrystaX's Android NDK which seems to have extensions over the Vanilla Android NDK.

Note: __GXX_EXPERIMENTAL_CXX0X__ is defined by adding -std=gnu++11 to APP_CXXFLAGS or LOCAL_CXXFLAGS

Detailed Test log: Built using NDK version r8e
jni/Application.mk:

APP_STL := gnustl_static APP_CXXFLAGS += -std=gnu++11 NDK_TOOLCHAIN_VERSION := 4.7 

jni/Android.mk

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE    := cxx11 LOCAL_SRC_FILES := cxx11.cpp include $(BUILD_EXECUTABLE) 

jni/cxx11.cpp:

#include <iostream> #include <string>  int main(int argc, char* argv[]) { #if defined(__GXX_EXPERIMENTAL_CXX0X__)     std::cout<<"__GXX_EXPERIMENTAL_CXX0X__ defined."<<std::endl; #else     std::cout<<"__GXX_EXPERIMENTAL_CXX0X__ not defined."<<std::endl; #endif  #if defined(_GLIBCXX_USE_C99)     std::cout<<"_GLIBCXX_USE_C99 defined."<<std::endl; #else     std::cout<<"_GLIBCXX_USE_C99 not defined."<<std::endl; #endif  #if defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)     std::cout<<"_GLIBCXX_HAVE_BROKEN_VSWPRINTF defined."<<std::endl; #else     std::cout<<"_GLIBCXX_HAVE_BROKEN_VSWPRINTF not defined."<<std::endl; #endif  #if (defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99) \      && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))     std::string s="1";     std::cout<<"ll:"<<std::stoll(s)<<std::endl<<"ul:"<<std::stoul(s)<<std::endl; #else     std::cout<<"No support for stoll/stoul."<<std::endl; #endif     return(0); } 

Output on Nexus 4 (Android 4.3):

u0_a51@mako:/ $ /data/local/tmp/cxx11 __GXX_EXPERIMENTAL_CXX0X__ defined. _GLIBCXX_USE_C99 not defined. _GLIBCXX_HAVE_BROKEN_VSWPRINTF not defined. No support for stoll/stoul. 
like image 117
Samveen Avatar answered Oct 11 '22 15:10

Samveen


Adding:

APP_STL := c++_static

to Application.mk fixed my issue of not being able to access std::stoi() (using gcc 4.8.4).

solution via Daniel Tavares, from this Google Groups post.

like image 25
Mark S. Avatar answered Oct 11 '22 15:10

Mark S.