Does casting a char array to another type violate strict-aliasing rules?
Asked Answered
O

1

14

Consider these two functions:

int f1()
{
  alignas(int) char buf[sizeof(int)] = {};
  return *reinterpret_cast<int*>(buf);
}

int f2()
{
  alignas(int) char buf[sizeof(int)] = {};
  char* ptr = buf;
  return *reinterpret_cast<int*>(ptr);
}

GCC warns that the first violates strict-aliasing rules. But the second is OK.

Clang accepts both without complaint.

Is the warning legitimate?

Orvalorvan answered 23/12, 2016 at 9:25 Comment(2)
Yes. The "object" here is either a char or the array of chars and the glvalue is of type int; nothing in timsong-cpp.github.io/cppwp/basic.lval#8 covers this case.Culbreth
@Culbreth do you mean it's impossible by standard, to alias a region of char, as some other type T ? because that's how optional and variant works isn't it. I can't help but to find this idea, if true, a risk to a these practical needs. I thought the exceptions to aliasing were including char for that purpose.Heterodoxy
C
10

The warning is legitimate. f2 is not OK (it is undefined behaviour), it just doesn't provoke the warning.

I suspect the reason that f2 doesn't provoke the warning is that:

int f3()
{
    int i = 0;
    char *ptr = reinterpret_cast<char*>(&i);
    return *reinterpret_cast<int*>(ptr);
}

Is entirely legal. You can use a char* (or a void*) as a "universal pointer" - provided you cast back to the right type before access. GCC is clearly being careful to avoid warning about f3, at a cost of not warning about f2.

Clang is failing to warn about either f1 or f2 - but it is not required to.

Coed answered 23/12, 2016 at 10:0 Comment(1)
Needs standard quotes.Sunday

© 2022 - 2024 — McMap. All rights reserved.