On Mon, Feb 3, 2020 at 1:41 AM Xi Ruoyao <xry111@xxxxxxxxxxxxxxxx> wrote: > On 2020-02-03 01:34 -0800, J Decker wrote: > > On Mon, Feb 3, 2020 at 1:29 AM aotto <aotto1968@xxxxxxxxxxx> wrote: > > > > > Hi, > > > > > > this is a test: https://godbolt.org/z/8PpX8W > > > > > > > why is method_base(&aO->obj, 1); so much worse than method_base(aO, 1); > > it's the same resulting code... > > > > > > method_base(aO, 1); > > mov rax, QWORD PTR [rbp-8] > > mov esi, 1 > > mov rdi, rax > > call method_base > > > > method_base(&aO->obj, 1); > > mov rax, QWORD PTR [rbp-8] > > mov esi, 1 > > mov rdi, rax > > call method_base > > > > and there's no forced cast.... > > If a0 is NULL, the standard specifies "(base *) a0" will also be NULL > (6.3.2.3 > p4). But, &a0->obj is undefined behavior. > While true; that's not necessarily any sort of issue... other than perhaps finding words to describe it. It doesn't require dereferencing the pointer to get the value that is 'obj'. It's just (address that is a pointer of some type) + ( offsetof( type, member ) ) which does yield a non-NULL result > > Considering: > > method_base(&a0->obj); > > if (a0 != NULL) > return -EINVAL; > > this is an entirely different case, requiring getting the value of the structure member. > return a0->foo + 233; > > Then an optimizing C compiler could do some analysis: > > (1) If a0 is NULL, &a0->obj invokes undefined behavior. There is no > requirement > from the standard so we don't need to consider this situation. > > (2) If a0 is not NULL, the if statement is useless and can be optimized > away. > > So the code may be optimized to: > > method_base(&a0->obj); > return a0->foo + 233; /* crash when a0 is NULL */ > -- > Xi Ruoyao <xry111@xxxxxxxxxxxxxxxx> > School of Aerospace Science and Technology, Xidian University > >