Strict aliasing violation
Asked Answered
A

2

6

Does the following program violate the strict aliasing rule?

#include <cstdint>

int main()
{
    double d = 0.1;

    //std::int64_t n = *reinterpret_cast<std::int64_t*>(&d); // aliasing violation

    //auto n{*reinterpret_cast<std::int64_t*>(&d)}; // aliasing violation

    auto nptr{reinterpret_cast<std::int64_t*>(&d)};
    auto& n{*nptr};

    ++n;
}

No warning emitted by VS2015, clang or gcc.

Aestivation answered 23/6, 2016 at 17:23 Comment(0)
D
5

Does the following program violate the strict aliasing rule?

Yes, it does. You are dereferencing a double* (&d) using a std::int64_t*.

The line that violates strict aliasing rule is:

auto& n{*nptr};

While processing the line, the compilers don't necessarily know how you set the value of nptr. The fact that it is an alias to a double* is not obvious while processing that line.

Damper answered 23/6, 2016 at 17:26 Comment(0)
M
5

Yes, this violates strict aliasing. You are accessing an object d of type double, though a pointer nptr which is not a pointer to double or any type related to it.

Just because a compiler does not emit a warning does not mean it isn't a violation. Violations of strict arising are UB (since they're a matter of runtime behavior) and therefore do not require a diagnostic.

Monumental answered 23/6, 2016 at 17:26 Comment(4)
Re " Violations of strict [aliasing] are UB", not at all. Strict aliasing is a gcc notion connected to its optimization. The C++ standard instead has rules about how the results of reinterpretation can be used (or not) in portable ways. In this example that causes formal UB. But the example can be good on a given platform.Telly
@Cheersandhth.-Alf: "The C++ standard instead has rules about how the results of reinterpretation can be used (or not) in portable ways." And those rules are generally called the "strict aliasing rules"; the term may come from a GCC option, but the rules themselves do not. So I don't see what your point is. And no, the example is not allowed to be well-defined behavior on any platform. 3.10/10 does not allow you to ever access the value of a double through the a pointer to int64_1.Monumental
The view that C and C++ can't do type punning on specific platforms is contrary to reality. So that response is a very good example of what I attempted to point out. Unfortunately that view makes g++ (and clang as a plug-in replacement) less practically useful than it could have been.Telly
@Cheersandhth.-Alf: "The view that C and C++ can't do type punning on specific platforms is contrary to reality." That's not the "view" at all. The "view" is that the C++ standard does not protect it. If you want to rely on type punning, that's fine; you are simply relying on undefined behavior. If you want to do that, that's fine. But you cannot pretend the standard does not declare it to be UB.Monumental

© 2022 - 2024 — McMap. All rights reserved.