C ++ 11 cmath函数不在android NDK w / gcc-4.8或clang 3.4的std命名空间中

时间:2014-04-07 20:57:40

标签: android c++ c++11 stl android-ndk

在C ++ 11之后,当包含cmath标题时,先前在全局命名空间中的各种std函数被移动到<cmath>命名空间。

然而,Android NDK版本存在问题,包括gcc-4.8和clang-3.4工具链。

C++11标志已正确指定,因为unique_ptr等其他c ++ 11详细信息正常工作。

如果我尝试使用std::roundstd::cbrt,编译器会说这些在std::命名空间中不存在,他们应该[1]。它们存在于全局命名空间中,但我不想使用它们。

这是一个已知问题吗?我忽略了什么吗?有解决方法吗?

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


  • 桌面版本使用gcc-4.8.1没有这个问题,我使用gcc警告最充分地使用-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

  • 相关的构建命令,尽在其中: /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

2 个答案:

答案 0 :(得分:4)

这似乎是一个已知的问题,在Android上支持C ++ 11。有is a known issue表示缺少许多例程:

  

使用-std=c++11编译c ++代码并使用gnustl_shared时,<cmath>标头不会提供许多C99数学函数。

你可能最好假设只有c ++库的一个有限子集可用于android - 这似乎在CPLUSPLUS-SUPPORT.html的{​​{1}}文件中表示为ndk。

当我拥有时,请注意:

docs/

在我的APP_STL := c++_static

Application.mk

在我的LOCAL_CPPFLAGS := -std=c++11 中,然后使用Android.mkstd::cbrt的文件干净地编译;但它违反了静态LLVM libc ++,而不是针对gnu标准库。

答案 1 :(得分:2)

如果功能确实缺失,您必须自己编写(或从其他实现中复制它们)。

在Android NDK中,某些功能似乎存在,但仅在namespace std之外。我通过向round添加函数round解决了namespace std函数的相同问题,该函数仅从全局范围内回退到round函数。

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

如果要以便携方式使用它,则必须使用预处理器宏来保护它。