#Code is UB, but why?! (Effective types and aliasing)

9 messages · Page 1 of 1 (latest)

gleaming zinc
#

Hello, here is a follow up thread about #1373391268524199966 . I open a new thread to refocus the discussion on a closely related topic

I'm considering this code (https://godbolt.org/z/9fd3zc7To):

struct Foo { int a; };
struct Bar { int a; };
void f(struct Bar *y, struct Foo *x) {
  y->a = 7;
  x->a = 5;
  y->a += 4;
  x->a *= 3;
}
int main(void)
{
    void *z = malloc(128);

    f(z, z);

    struct Foo *x = z;
    printf("a=%d\n", x->a);
}

I used to think f has UB because of strict aliasing rules. however, the article https://www.open-std.org/jtc1/sc22/WG14/www/docs/n3519.pdf makes me doubt

going through the example, it looks to me (with the perspective of the author, I mean) like that none of struct Foo nor struct Bar, will become the effective type for the allocated object (because none of the lvalue are actually of that type: they all have type int)

to inside of f, it looks to me that the object(s) referred to from x and y, are actually int effective types. Therefore, the code should actually not be UB ??????

I'm extremely confused: could someone with a clear interpretation of the spec help me walk through. the example, step by step, and tell me who has which effective type and why?

exotic pagodaBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

quaint patrol
#

That definitely looks like UB to me for precisely the reason you mentioned but I want to give a full answer after reading that document because my impression was that I understand effective types and it definitely seemed to me like a lot of people do. Yet someone on the committee says that less than 10 people understand it. Although, to be frank, I feel like that person just pulled that out of their arse because they didn't know about it and figured no one else does. It seems crazy to me to program in C for 25 years and be on the committee but only find out about them now. I've talked about effective types with hundreds of people online over the years.

#

So I'll come back to this after I get a little bit of time to read what he's on about, just to make sure I'm not missing anything.

gleaming zinc
#

I think it actually bowls down to what we mean by "access to the store value" of an object.
when doing this:

x->a = 2;

do we access the stored value of the object through the lvalue *(x) of type struct Foo (for example), or else is the lvalue *(x)->a

and I think the author of the article has the radical interpretation that the lvalue here should be *(x)->a. which kind of makes sense. but on the other hand, it also means that the function g I sketched above, should be entirely well defined. yet clang clearly was interpreting things differently

sharp socket
#

I disagree with his 4th example:

int *ip;
float *fp;
ip = calloc(sizeof *fp);
fp = (float *)ip;
y = *ip;
x = *fp;```
He says it’s UB, but I think it falls under the final clause of the rules: “For all other accesses to an object of no declared type, the effective type of the object is simply the type of the lvalue used for the access.” It says nothing about subsequent access so it would be int in the first access and float in the second access
gleaming zinc
#

I agree with you

gleaming zinc
#

!solved

exotic pagodaBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity