Android项目迁移至clang/libc++时vector<JSONValue*>初始化编译失败
Let’s break down what’s happening here and how to resolve it.
Your error comes down to a key difference between GCC and clang/libc++ when handling null pointers in C11 mode. GCC allows lenient implicit conversions between integer types (like long, which is what NULL typically expands to) and pointer types, but libc follows stricter C++11 standard rules—hence the error about not being able to initialize a JSONValue** with a long (your NULL).
Here are the most straightforward fixes to get your code compiling again:
1. Replace NULL with nullptr everywhere
Since you’re using -std=c++11, switch all instances of NULL (when used as a null pointer) to nullptr. This is the C11 standard way to represent null pointers, and libc handles it correctly without conversion issues because nullptr is explicitly typed for pointers, unlike NULL which is just an integer 0.
For example, if your JSONValue default constructor implementation has code like:
JSONValue::JSONValue() { // ... array_value.push_back(NULL); // ... }
Change it to:
JSONValue::JSONValue() { // ... array_value.push_back(nullptr); // ... }
2. Enable C03 compatibility in libc
If you need to keep using NULL and other C03 idioms without modifying the code, add the compiler flag -D_LIBCPP_ENABLE_CXX03_FEATURES to your build configuration. This tells libc to relax its C++11 strictness and allow the implicit conversions that GCC permits.
To add this in Android Studio:
- Open your module’s
build.gradlefile - In the
externalNativeBuildsection, add the flag tocppFlags:externalNativeBuild { cmake { cppFlags "-std=c++11", "-D_LIBCPP_ENABLE_CXX03_FEATURES" } }
3. Verify your JSONValue default constructor
Looking at your header code, the default constructor is declared as JSONValue(/*NULL*/);—this comment suggests it might have originally been intended to take a null pointer argument, but it’s now a no-arg default constructor. Double-check that the implementation isn’t doing something unexpected, like trying to initialize a pointer member with NULL in a way libc++ rejects.
Why this worked with GCC
GCC has historically allowed implicit conversions from integer literals (like 0) to pointer types in more contexts than the C++ standard strictly requires. libc++, however, adheres more closely to the standard—especially in C++11 mode—so you’re seeing this error now that you’ve switched compilers.
内容的提问来源于stack exchange,提问作者Kevin Murphy

