13

After C++11, various cmath functions previously in the global namespace are moved to the std namespace, when including the <cmath> header.

However the android NDK build has issues with this, with both gcc-4.8 and clang-3.4 toolchains.

The C++11 flag is correctly specified, as other c++11 particulars like unique_ptr work fine.

If i attempt to use std::round, or std::cbrt, the compiler says these don't exist in std:: namespace, which they should [1]. They exist in the global namespace, but I don't want to use those.

Is this a known issue? Have I overlooked something? Are there workarounds?

[1] http://en.cppreference.com/w/cpp/header/cmath


  • The desktop build does not have this problem using gcc-4.8.1, and I use gcc warnings to its fullest with -Wall -Wextra -Wcast-align -Wcast-qual -fpermissive -Wconversion -Wdisabled-optimization -Weffc++ -Wfloat-equal -Wformat=2 -Wimport -Winit-self -Winline -Winvalid-pch -Wlong-long -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wshadow -Wstack-protector -Wstrict-aliasing=2 -Wunreachable-code -Wunsafe-loop-optimizations -Wunused -Wvariadic-macros -Wwrite-strings -pedantic -pedantic-errors -Woverloaded-virtual -Wswitch-enum -Werror

  • Relevant build command, in all its glory: /opt/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi/objs/main/__/android/jni/src/main.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fno-rtti -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Ijni/src/../android/jni/SDL/include -Ijni/src/../android/jni/SDL_image -Ijni/src/../android/jni/SDL_mixer -I/opt/bullet/bullet-2.82/include/bullet -I/opt/glm/glm-0.9.5.2 -I/opt/android-ndk-r9d/sources/android/cpufeatures -Ijni/SDL/include -Ijni/SDL_image -Ijni/SDL_image/external/jpeg-9 -Ijni/SDL_image/external/libpng-1.6.2 -Ijni/SDL_mixer -Ijni/SDL_mixer/external/libmodplug-0.8.8.4/src -Ijni/SDL_mixer/external/libmodplug-0.8.8.4/src/libmodplug -Ijni/SDL_mixer/external/smpeg2-2.0.0 -Ijni/SDL_mixer/external/libogg-1.3.1/include -Ijni/SDL_mixer/external/libvorbisidec-1.2.1 -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/include -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/include/backward -Ijni/src -DANDROID -fno-strict-aliasing -D_REENTRANT -DGLM_FORCE_RADIANS -isystem /opt/glm/glm-0.9.5.2 -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -fexceptions -frtti -I/opt/android-ndk-r9d/platforms/android-19/arch-arm/usr/include -c jni/src/../android/jni/src/main.cpp -o ./obj/local/armeabi/objs/main/__/android/jni/src/main.o

swalog
  • 4,403
  • 3
  • 32
  • 60
  • Also see [error: 'log2' is not a member of 'std'](http://stackoverflow.com/a/41514011/608639) for one of the reason GCC does not import the C99 math functions into `std` namespace. The cited question is about an older PowerMac G5, and I am not sure how well it intersects with modern Android. – jww Jan 06 '17 at 20:45

2 Answers2

4

This seems to be a known issue with C++11 support on android. There is a known issue that indicates that a lot of the routines are missing:

When compiling c++ code with -std=c++11 and using gnustl_shared, many C99 math functions are not provided by the <cmath> header as they should.

You're probably better off assuming that only a limited subset of the c++ library is available for android - this seems to be indicated in the CPLUSPLUS-SUPPORT.html file in the docs/ for the ndk.

Mind you when I have:

APP_STL := c++_static

in my Application.mk and

LOCAL_CPPFLAGS  := -std=c++11

in my Android.mk, then files making use of std::cbrt and std::round compile cleanly; but it is against the static LLVM libc++, rather than against the gnu standard library.

Anya Shenanigans
  • 91,618
  • 3
  • 107
  • 122
  • 1
    For some reason I read an old version of the CPLUSPLUS-SUPPORT.html, which didn't list the LLVM libc++. This solved several issues I had. Most notably the gnustl GPLv3 problem. Usually I wait a few weeks before accepting answers, but I don't see what else can be added. Thank you. I ended up going with c++_shared, which also had no issues. – swalog Apr 07 '14 at 23:49
3

If functions are really missing, you have to write them yourself (or copy them from some other implementation).

In the Android NDK, some functions seem to be there, but just outside of namespace std. I have worked around the same issue for the round function by adding a function round to namespace std, which just falls back on the round function from the global scope.

namespace std
{
    inline int round(float x)
    {
        return ::round(x);
    }
}

If you want to use this in a portable way, you would have to protect this with preprocessor macros.

  • Also see [error: 'log2' is not a member of 'std'](http://stackoverflow.com/a/41514011/608639) for one of the reason GCC does not import the C99 math functions into `std` namespace. The cited question is about an older PowerMac G5, and I am not sure how well it intersects with modern Android. – jww Jan 06 '17 at 20:47