Skip to content

Nit: Use of C++ UB #10

@cculianu

Description

@cculianu

Hey man first off thanks for writing a great tool. I have no idea how you managed to reverse-engineer the save file format -- but good job.

Also good job with the map UI -- I'm blown away by it. Great great work.

I just had 1 nit -- in the C++ -- there is technically "undefined behavior" with expressions that deserialize the file format. Stuff such as: someFloat = *reinterpret_cast<const float *>(&someString[1])

Seen e.g. here:

(std::abs(*reinterpret_cast<const float*>(v1->at(i1).value.substr(1, 4).c_str()) - *reinterpret_cast<const float*>(v2->at(i2).value.substr(1, 4).c_str())) >= options->FloatDelta) ||

You're not supposed to really do that in C++ -- there's no guarantee it will end up working across platforms, etc, due to memory alignment. It also may or may not break strict aliasing rules to do that. I can link you to the standard where it talks about this.

In practice, since this app is supposed to only run on windows, and only on x86_64 (which supports unaligned access) -- it's more of a nit. The code you have here compiles ok on MSVC and will run ok 100% of the time, I think.

So .. it doesn't really matter. It's more of a nit.


In case you're curious -- if you can't reinterpret_cast like this -- how should this be handled? Well.. the way to handle it is to do a memcpy. For example:

template<typename Ret>
Ret data_cast(const char *data) {
    Ret ret;
    std::memcpy(reinterpret_cast<char *>(&ret), data, sizeof(ret)); // reinterpret_cast of &ret to char * needed here to tell compiler this variable will be aliased
    return ret;
}

// then later do:
myFloat = data_cast<float>(&myString[3]);  // or whatever...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions