0

Does the following program invoke undefined behavior? Assume the programmer has enough knowledge of ABI and class layout. The main thing that I am suspicious of is the line p1 += 2;, but I appreciate your comment on any other issue.

Please consider two cases: compiled with and without fno-strict-aliasing

#include <iostream>
using namespace std;

class X {
public:
  float f1;
  int i1;
  X() {
    f1 = 0;
    i1 = 0;
    f2 = 5.1;
    i2 = 1;
  }
  int *getPointer() { return &i1; }

private:
  float f2;
  int i2;
};

int main() {
  X x;
  int *p1 = x.getPointer();
  p1 += 2;
  cout << *p1 << "\n";
  *p1 = 2;
  cout << *p1 << "\n";
  return 0;
}

esam
  • 580
  • 3
  • 13
  • 3
    It absolutely invokes UB. It does not account for padding that the compiler can introduce anywhere it wants *except* prior to the first member. – WhozCraig Apr 09 '22 at 20:27
  • It also seems to assume that `sizeof(int) == sizeof(float)` – Ted Lyngmo Apr 09 '22 at 20:29
  • Thanks. I appreciate any reference to C++ standard. – esam Apr 09 '22 at 20:31
  • Is there a problem with the assumption about ```sizeof```? Let's say it works for my environment – esam Apr 09 '22 at 20:32
  • 1
    A better option would be to step `sizeof(float)` bytes. It'd still be UB though – Ted Lyngmo Apr 09 '22 at 20:35
  • 1
    Since you are asking for the standard reference: `p1 += 2` has undefined behavior because `p1` doesn't point to an object which is element of an array. Pointer arithmetic is defined only in arrays or one-past an object. https://eel.is/c++draft/expr.add#4.3 – user17732522 Apr 09 '22 at 21:57
  • 2
    Undefined behavior means that the language definition doesn’t tell you what the program does. If you have to make assumptions about what your compiler does you’re looking at undefined behavior. – Pete Becker Apr 09 '22 at 23:55
  • I think we also have something called "implementation-defined"? @PeteBecker – esam Apr 10 '22 at 02:06
  • @esam indeed the compilers can add their own implementation-defined for UB cases. In that case consult your compiler's documentation. Regarding the standard, this is UB – phuclv Apr 10 '22 at 02:20
  • @esam -- implementations can do whatever they want when the language definition says that the behavior Is undefined. "Undefined behavior" doesn't mean that something bad must happen; it **only** means that the C++ standard doesn't tell you what the program does. In the standard, "implementation defined" means that the implementation is required to document its behavior. There is no overlap between undefined behavior and implementation-defined behavior. – Pete Becker Apr 10 '22 at 12:58
  • Yes :) I know the difference between UB and implementation defined. My point was that, just the fact that something is not defined in the language standard doesn't make it UB. It should be explicitly defined as UB. – esam Apr 10 '22 at 13:10

0 Answers0