我想使用 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[])
^
据我了解,确保该函数始终在编译时运行
这不是
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" });
如何在宏中实现此功能取决于您。