3
char foo[n] = /*init here*/;  // n = 4*k + 4.
int i = 0;
while (i < n) {                            
   int four_bytes = *reinterpret_cast<const int*>(foo + i); // is this UB?
   bar(four_bytes);
   i += 4; 
}

In this snippet of code (assuming all data is initted properly, and that the array's length is a multiple of 4), is this reinterpret_cast UB?

C++14 and someetimes C++11

Curious Learner
  • 343
  • 2
  • 9

1 Answers1

1

Alignment

It is UB when the char foo[n] is not sufficiently aligned as an int array.

Size1

When 0 < n < sizeof(int), *reinterpret_cast<const int*>(foo + i); attempts to refence outside foo[].


1 Did not see "array's length is a multiple of 4" until later. Yet this still applies on unusual platforms where the sizeof int is larger, say 8. (eg. some graphics process of old). IOWs "array's length is a multiple of 4" is not specified the same as "array's length is a multiple of sizeof(int)"

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Can you clarify the alignment part? Specifically, what does "not sufficiently aligned for as an int array" mean? – Curious Learner Feb 18 '21 at 02:48
  • (regarding size, it's guaranteed that the array is large enough and that its length is a multiple of the sizeof(int)) – Curious Learner Feb 18 '21 at 02:48
  • @CuriousLearner Example: An `int` might only be allowed on even addresses and `foo[]` might start on an odd address. – chux - Reinstate Monica Feb 18 '21 at 02:52
  • Ah, I see. To ask a more general question, would the same issue occur if instead of `char`, the array was `int8`, then I tried to read 4 blocks as `int32`? (or `intx[]` and I wanted to read n blocks as `inty`, where `y = x * n` ?) – Curious Learner Feb 18 '21 at 02:53
  • @CuriousLearner No difference, alignment issue applies. – chux - Reinstate Monica Feb 18 '21 at 02:54
  • What would be the right way to do this then? read each element individually? – Curious Learner Feb 18 '21 at 02:55
  • 2
    The simplest right way is `int bytes; memcpy(&bytes, foo, sizeof bytes);` (when `n >= sizeof bytes`) and use a good compiler to emit efficient code. Recall there are endian concerns. In most cases, the _best_ approach depends on the larger code - something not posted. Avoid micro-optimization. – chux - Reinstate Monica Feb 18 '21 at 02:58