JustasMasiulis / xorstr

heavily vectorized c++17 compile time string encryption.
Apache License 2.0
1.21k stars 194 forks source link

Can't use xorstr_ in brace initializer #27

Closed ghost closed 4 years ago

ghost commented 4 years ago

I'm having a weird issue where I can't create an array of encrypted strings. When I run it in a debugger they just display as garbage, and upon further inspection it doesn't seem like the strings are being emitted at all, either encrypted or not. I'm pretty sure the garbage I'm seeing in the debugger is just random stuff that was on the stack already.

Example:

const char *test1[] = { xorstr_("abc"), xorstr_("123") };
const auto test2 = std::array { xorstr_("abc"), xorstr_("123") };

Am I doing something wrong?

ghost commented 4 years ago

Interestingly, this only occurs when compiling with /O1 or /O2. With /Od everything works as expected. This leads me to believe that all of it is getting optimized away by the compiler. Very weird.

If it matters, I'm using VS 2019 with /std:c++latest. I'm also using JM_XORSTR_DISABLE_AVX_INTRINSICS since my CPU doesn't support AVX2.

Edit: Yep, I was able to sort of work around this by wrapping this specific function with #pragma optimize. e.g.:


#pragma optimize( "", off )
void func() {
    const char *test1[] = { xorstr_("abc"), xorstr_("123") };
    for ( const auto &a : test1 ) { ... }
    const auto test2 = std::array { xorstr_("abc"), xorstr_("123") };
    for ( const auto &a : test2 ) { ... }
}
#pragma optimize( "", on )
ghost commented 4 years ago

Maybe also worth noting, defining the array first and then assigning to it does not work either. e.g.

std::array<const char *, 3> Names;
Names[0] = xorstr_("xxx");
Names[1] = xorstr_("yyy");
Names[2] = xorstr_("zzz");
for ( const auto &a : Names ) { ... }

So it isn't just init braces.

JustasMasiulis commented 4 years ago

duplicate #26

In all of the examples you have dangling pointers.

std::array<const char *, 3> Names;
Names[0] = std::array{"xxx"}.data();
...

Would be exactly the same.

If you want to store the xorstr for further processing you need to not make it a temporary.

auto xs = xorstr("test");
auto xs2 = xorstr("test2");
foo(xs.crypt_get());
foo(xs.get());
bar(xs.get(), xs2.crypt_get());
ghost commented 4 years ago

Doh! Its obvious now that you put it like that, I feel like an idiot. Thanks for the quick reply and great library! 😄