Live data from Hacker News

Understanding effective type Aliasing in C [pdf]

open-std.org

1–10 of 19 posts

Re: Understanding effective type Aliasing in C [pdf]

#2
It’s fun to consider how C devolves into assembler. In my mind, C and its derivatives dissolve into 68K assembler as I’m writing or debugging. Thinking about code this way lets me get a feel for how all the bits all fit together.

It seems like a lost art to think that way. It’s disturbing to me how many candidates couldn’t write Hello World and compile it from the command line.

Everyone should spend some time with godbolt.org or better, the -save-temps compiler flag, to see how changes affect your generated code. Right now. I’ll wait. (Shakes cane at kids)

Re: Understanding effective type Aliasing in C [pdf]

#3

It’s fun to consider how C devolves into assembler. In my mind, C and its derivatives dissolve into 68K assembler as I’m writing or debugging. Thinking about code this way lets me get a feel for how all the bits all fit together. It seems like a lost art to think that way. It’s disturbing to me how many candidates couldn’t write Hello World and compile it from the command line. Everyone should spend some time with go…

In the kernel developer world on the other hand, it's still very common to think about how the C code one writes translates into assembly. (Honestly, I think C should not be used much outside developing kernels anyway, and even there it's just legacy, but that's just personal opinion.)

But it's rough, and dangerous. Optimizers do a lot these days, and I really mean a lot. Besides completely mangling your program order, which includes shoving entire blocks of code into places that you might not have guessed, they also do such things as leveraging undefined behavior for optimizations (what the article is partly about), or replacing entire bits of code by function calls. (A compiler might make code out of your memcpy(), and vice versa; the latter can be especially surprising.)

If you care about the assembly representation of your C code (which kernel developers often do), you will spend a lot of time with the "volatile" keyword, compiler barriers, and some obscure "__attribute__"s.

But I agree, even with those caveats in mind, it's a very useful skill to imagine your C code as what it translates to (even if that representation is just a simplified model of what the compiler will actually do).

Re: Understanding effective type Aliasing in C [pdf]

#4

It’s fun to consider how C devolves into assembler. In my mind, C and its derivatives dissolve into 68K assembler as I’m writing or debugging. Thinking about code this way lets me get a feel for how all the bits all fit together. It seems like a lost art to think that way. It’s disturbing to me how many candidates couldn’t write Hello World and compile it from the command line. Everyone should spend some time with go…

How is this related to the linked article? Assemblers won’t delete your code for treating a register with a float in it like an integer.

Re: Understanding effective type Aliasing in C [pdf]

#5
> Any access of memory using a union, where the union includes the effective type of the memory is legal. Consider:

    union {
        int i;
        float f;
    } *u;
    float f = 3.14;
    u = &f;
    x = u->i;
> In this case the memory pointed to by “u” has the declared effective type of int, and given that “u” is a union that contains int, the access using the “i” member is legal. It’s noteworthy in this that the “f” member of the union is never used, but only there to satisfy the requirement of having a member with a type compatible with the effective type.

Is this a typo? Should it say "declared effective type of float" and "“u” is a union that contains float"?

It's interesting to see type-punning using a union - I've read that it should be avoided and to use `memcpy` instead. Are there any issues with the union approach in C? Or is the advice to prefer `memcpy` specific to C++, where AFAICT the union approach is undefined behaviour?

Re: Understanding effective type Aliasing in C [pdf]

#6
post #5

> Any access of memory using a union, where the union includes the effective type of the memory is legal. Consider: union { int i; float f; } *u; float f = 3.14; u = &f; x = u->i; > In this case the memory pointed to by “u” has the declared effective type of int, and given that “u” is a union that contains int, the access using the “i” member is legal. It’s noteworthy in this that the “f” member of the union is never…

> type-punning using a union - I've read that it should be avoided and to use `memcpy` instead

The other day we had standard committee members confirming union punning is good in C: https://news.ycombinator.com/item?id=43793225

Re: Understanding effective type Aliasing in C [pdf]

#7

It’s fun to consider how C devolves into assembler. In my mind, C and its derivatives dissolve into 68K assembler as I’m writing or debugging. Thinking about code this way lets me get a feel for how all the bits all fit together. It seems like a lost art to think that way. It’s disturbing to me how many candidates couldn’t write Hello World and compile it from the command line. Everyone should spend some time with go…

I kind of share this feeling (I knew 68K assembler before learning C), but having spent ~30 years writing C, publishing some open source software in C, reading comp.lang.c and draft standards, as well as answering many C questions on Stack Overflow back when it was cool, let me tell you: it's not a good model any more (if it ever was). :)

C is specified against an abstract (not virtual) machine, and it matters.

All the talk about how undefined behaviors give the compiler right to shuffle and/or remove code really break the analogy with assembler, where most things become Exactly What You Say.

Re: Understanding effective type Aliasing in C [pdf]

#8
post #6
post #5

> Any access of memory using a union, where the union includes the effective type of the memory is legal. Consider: union { int i; float f; } *u; float f = 3.14; u = &f; x = u->i; > In this case the memory pointed to by “u” has the declared effective type of int, and given that “u” is a union that contains int, the access using the “i” member is legal. It’s noteworthy in this that the “f” member of the union is never…

> type-punning using a union - I've read that it should be avoided and to use `memcpy` instead The other day we had standard committee members confirming union punning is good in C: https://news.ycombinator.com/item?id=43793225

Thanks, I didn’t see that discussion at the time.

Re: Understanding effective type Aliasing in C [pdf]

#9
What drugs were they on? Why on earth is there any distinction between variables allocated statically, on the stack, or on the heap? I allocate a struct, copy data to it, and those data have no Effective Type? Because I started with malloc? Give me a break.

The point of the type system is to define types. It’s not to make the compiler’s job easier, or to give standards committees clouds to build their castles on. No amount of words will justify this misbegotten misinvention.

Re: Understanding effective type Aliasing in C [pdf]

#10
post #9

What drugs were they on? Why on earth is there any distinction between variables allocated statically, on the stack, or on the heap? I allocate a struct, copy data to it, and those data have no Effective Type? Because I started with malloc? Give me a break. The point of the type system is to define types. It’s not to make the compiler’s job easier, or to give standards committees clouds to build their castles on. No…

> If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value

As I read it, this means that

  struct foo *x = malloc(sizeof(*x))
Will have an effective type of "struct foo*", which seems like what you would expect.
Post reply on HN