在C ++ 11之后,当包含cmath
标题时,先前在全局命名空间中的各种std
函数被移动到<cmath>
命名空间。
然而,Android NDK版本存在问题,包括gcc-4.8和clang-3.4工具链。
C++11
标志已正确指定,因为unique_ptr
等其他c ++ 11详细信息正常工作。
如果我尝试使用std::round
或std::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
答案 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.mk
和std::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);
}
}
如果要以便携方式使用它,则必须使用预处理器宏来保护它。