consteval:调用 consteval 函数 'encrypt_string' 不是常量表达式,指向临时子对象的指针不是常量表达式

问题描述 投票:0回答:1

我想使用 consteval 关键字在 C++ 中创建一个简单的字符串加密。以前,我使用 constexpr,它可以工作,但某些字符串在运行时被加密。因此,我决定改用 consteval,据我了解,这可以确保函数始终在编译时运行。

现在我收到此错误:

Call to consteval function 'encrypt_string' is not a constant expression
pointer to subobject of temporary is not a constant expression

我不确定这是什么意思。

目前我正在使用宏来加密字符串,并将其替换为以下代码:

decrypt_string(encrypt_string((char[]) { "s/x/apkpath/MainActivity" }, sizeof(char[])
    { "s/x/apkpath/MainActivity" }),sizeof(char[])
    { "s/x/apkpath/MainActivity" })

encrypt_string()
是声明 consteval 的函数。

这两个函数如下所示:

consteval auto encrypt_string(char string[], uint32_t len) {
    for (int i = 0; i != len; i++) {
        string[i] = string[i] ^ keys_expr[i & 7];
    }
    return string;
}

__attribute__((visibility("hidden"))) __attribute__((noinline)) __attribute__((optnone))
auto decrypt_string(char string[], int len) {
    for (int i = 0; i != len; i++) {
        string[i] = (string[i] & ~keys[i & 7]) | (~(string[i] & keys[i & 7]) & keys[i & 7]);
        //string[i] = string[i] ^ keys[i & 7];
    }
    return string;
}

我正在 Android Studio 中编译它,所以编译器应该是 clang 的。 我将这一行添加到 build.gradle

externalNativeBuild {
    cmake {
        cppFlags '-std=c++20'
    }
}

这是完整的错误:

C:\Users\*\AppData\Local\Android\Sdk\ndk\25.1.8937393\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android24 --sysroot=C:/Users/*/AppData/Local/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/sysroot -Dapkpath_EXPORTS  -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security  -std=c++20 -fno-limit-debug-info  -fPIC -MD -MT CMakeFiles/apkpath.dir/apkpath.cpp.o -MF CMakeFiles\apkpath.dir\apkpath.cpp.o.d -o CMakeFiles/apkpath.dir/apkpath.cpp.o -c C:/Users/*/AndroidStudioProjects/ApkPath/app/src/main/cpp/apkpath.cpp

C:/Users/*/AndroidStudioProjects/ApkPath/app/src/main/cpp/apkpath.cpp:15:17: error: call to consteval function 'encrypt_string' is not a constant expression
        decrypt_string(encrypt_string((char[]) { "s/x/apkpath/MainActivity" }, sizeof(char[])
                       ^
C:/Users/*/AndroidStudioProjects/ApkPath/app/src/main/cpp/apkpath.cpp:15:17: note: pointer to subobject of temporary is not a constant expression
C:/Users/*/AndroidStudioProjects/ApkPath/app/src/main/cpp/apkpath.cpp:15:32: note: temporary created here
        decrypt_string(encrypt_string((char[]) { "s/x/apkpath/MainActivity" }, sizeof(char[])
                                      ^
android c++ c++20 constexpr consteval
1个回答
0
投票

据我了解,确保该函数始终在编译时运行

这不是

consteval
所做的。
consteval
函数不允许在常量求值之外的地方调用(因此得名)。它不会“导致”调用是“编译时”的;它只是禁止在此类评估之外使用。 您可以在持续评估期间使用

consteval

功能。对

decrypt_string
的调用不是常量求值,因此在该表达式期间调用
encrypt_string
将不在常量求值范围内。因此出现错误。
您想要的是创建一个 

constexpr

变量来存储

encrypt_string
的结果,然后您可以将其传递给
decrypt_string
:
constexpr auto estr = encrypt_string((char[]) { "s/x/apkpath/MainActivity" }, sizeof(char[])
    { "s/x/apkpath/MainActivity" });

decrypt_string(estr, sizeof(char[]){ "s/x/apkpath/MainActivity" });

如何在宏中实现此功能取决于您。

© www.soinside.com 2019 - 2024. All rights reserved.