使用 Android NDK 在 constexpr 构造函数 (c++17) 中分配给 const char * 失败

Assigning to const char * in constexpr constructor (c++17) fails using Android NDK

我正在尝试使用编译时字符串 类 的修改版本 post:https://akrzemi1.wordpress.com/2017/06/28/compile-time-string-concatenation/

这样做的原因是一堆字符串文字需要根据编译时常量进行调整,因此在编译时而不是在运行时进行这种调整是有意义的。

因为我能够在项目中使用 c++17,所以我可以利用对 constexpr 构造函数的宽松限制。给我留下以下(简化的)代码:

template<int N>
class array_string {
    char _array[N + 2 + 1];
    
public:
    constexpr array_string(const char (&sl)[N + 1]) {
    
        int j = 0;
                
        // here some work based on sl is actually done, but compilation also fails if removed
     
        // overwrite remaining elements with zero bytes.
        for (; j < N + 2 + 1; j++) {
            _array[j] = '[=11=]';
        }
    
    }
    
    constexpr const char *c_str() const { return _array; }
};
    
// C++17 deduction guide:
template<int N_PLUS_1>
array_string(const char (&lit)[N_PLUS_1])   
-> array_string<N_PLUS_1 - 1>;

如果我通过以下方式在代码的其他位置强制创建 constexpr 变量:

constexpr auto cmpStr = array_string("test");  

使用我的 Linux-Desktop 机器使用 clang 10 和 libc++,一切都按预期编译。 (我还检查了修改后的字符串是否包含在二进制文件中。它们是!)。 然而,当我试图为 android 编译相同的代码时,我收到以下错误消息:

error: constexpr variable 'cmpStr' must be initialized by a constant expression

错误似乎出在构造函数体内对 _array 的赋值。我现在真的很困惑,因为我认为从 c++14 开始就允许这样做。由于项目中的其他 c++14/c++17 功能正在运行(例如演绎指南),我真的很困惑为什么这不是。

网上找资料说ndk不支持这个功能,但是没有找到。可能我没有找到合适的关键字来搜索。

到目前为止,我正在删除 cmpStr 上的 constexpr 约束以使其针对 android 进行编译,这很可能会导致构造函数代码在运行时执行,这有点令人不满意。

如果有人能指出为什么这在使用 android ndk 或任何其他问题时不起作用,我会很高兴。提前致谢!

构建过程的一些细节:

几个月后,我实际上注意到,如果我显式初始化 array_string 成员,它也适用于 android。

template<int N>
class array_string {
    char _array[N + 2 + 1]{}; // use default {}-initialization
    
public:
    // ... see code from question