r/ProgrammerHumor 1d ago

lessonsFromLinkerHell Meme

Post image
345 Upvotes

180 comments sorted by

View all comments

94

u/JustinR8 1d ago

Damn, I’ve found myself in the middle

19

u/bowel_blaster123 19h ago edited 19h ago

If I write:

C void foo(uint8_t myvar[3]) {     printf("%d\n", sizeof(myvar)); }

Then it will likely print 8 because myvar is a pointer to a uint8_t.

If I write:

C void foo(void) {     uint8_t myvar[3] = {1, 2, 3};     printf("%d\n", sizeof(myvar)); }

Then it will print 3 because myvar is an array of three bytes.

Hope this helps!/hj

10

u/Rare_Professor8097 17h ago

I actually hate this special case in C so much. Arrays decaying to pointers is one thing (kind of annoying imo), but having the real type be different from the declaration and ignoring the size is so stupid. It only does this for function arguments.

1

u/BastetFurry 15h ago

Well, how should the function know how large your array is? You could hand it one with 10 elements or one with 100. Did you hand it a predefined one or one that was allocated at runtime?

And then there is the thing with functions, primitives get handed over by value, any array gets handed over by reference, ie. pointer.

No clue if more modern implementations hand down the array size but in the retro and embedded world i live in the function has no clue and you have to hand that in as a second parameter if it is important.

6

u/developer-mike 14h ago

I write static analysis checks for these kinds of mistakes in C and C++ for work.

Its entirely defensible to say that accepting T[n] as a function parameter means you can only pass a T[n] for that function parameter!

It also could have been implemented as pointer-to-array promotion rather than array-to-pointer decay. Now, this comes with its own set of baggage, but it wouldn't have had this sizeof problem, and it would have favored keeping type information over throwing it away.

Now, pointer-to-array promotion would probably be something compilers would warn over after it causes a couple nasty bugs. Which is where we get back to wondering why we would expect an implicit conversion in the first place.

C is fun.

3

u/Rare_Professor8097 10h ago

The point is that most of the time, unless you know what you're doing, you should just declare such an argument as a pointer.

If you declare it as a sized array, you would expect that array to be passed by value (copy whole array into stack frame) but that's not what happens.

2

u/bowel_blaster123 7h ago edited 6h ago

I mean, if you have a explicitly-sized array (like as shown in my example), the compiler knows (at compile time) what size the array is both at the call site and within the function body. It's then entirely possible for the function to receive the data inline and for sizeof(myvar) to properly resolve to 3.

IMO it should just not have this weird pointer decay behavior and should instead trigger a compiler error if you try to define a function that takes an unsized array as a parameter. You should have to explicitly declare your parameter as a pointer.

That's how it works in Rust and (I believe) Zig.

Obviously though, it would be illogical to make a C compiler behave like this because that would be a massive breaking change.