Nope, int a[] is a fundamentally a pointer in that context. If it were a whole array, it would be a full copy, and so would have a different address. Print the value of a (as a pointer: %p) in caller and callee, you will see that it is the same.
Nope, int a[] is a fundamentally a pointer in that context. If it were a whole array, it would be a full copy, and so would have a different address. Print the value of a (as a pointer: %p) in caller and callee, you will see that it is the same.
Warning: unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
Thanks ofnuts.
But do you think this syntax which conveys different meaning as per the context is slightly messy/confusing, or is it just me?
Obviously, the people who came up with this really smart and there might be different things that prevented them from having an easier syntax, but it still is confusing?
Warning: unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
I've been sans-Internet for a few days, but I have a different answer to this:
In fact, I agree. It's downright weird that "int a[10]" declares a as pointer-to-int when it's a function parameter, but array[10]-of-int otherwise. Even weirder is the fact that this "pointer decay" rule doesn't apply to structs, so you can pass an array by-value simply by wrapping it in a struct, which defeats the very principle (function calls don't cause arbitrarily large copies) that makes pointer-decay useful.
The fact that arrays decay into pointers at all -- that I'm not arguing with. It's pretty logical, really. (But keep the exceptions in mind: when it's the argument of sizeof or the & operator, an array name does not decay.) If I were to design C today, though, I'd make "int f(int a[10])" invalid syntax. As it is, I just don't write function prototypes like that.
At the end of the day, this is one of those historical curiosities you find in C. It wasn't designed all at once, and it wasn't standardized until it had been in use for many years, so once in a while you run into things that don't really make sense from a design perspective. (Another one is the fact that string literals are non-const -- "const" wasn't in the language to begin with, and when it was introduced, changing the type of string literals would have affected the compilation of working code. You can make string literals const by compiling with -Wwrite-strings.) C isn't a perfect language, but we like it anyway
Haha thanks trent.josephsen. Feel like I'm making progress.
Absolutely! Would've been so good if int f(int a[10]) was invalid syntax, and all we needed was int* a.If I were to design C today, though, I'd make "int f(int a[10])" invalid syntax. As it is, I just don't write function prototypes like that..
How do you write your function prototypes?
Absolutely, easy for me to complain. I too realize that C is amazing.C isn't a perfect language, but we like it anyway
There is a fundamental difference between pointer an array that explains the behavior. An array variable is a pointer to a fixed memory area (which is the one established by the array variable declaration). As such it has a real sizeof() that represents the size of the memory area, and it cannot be assigned to (it is truly a constant and cannot be an "lvalue"(*)) When you use the array name in an expression it is converted to a pointer type (a pointer to the first element) with two exceptions: sizeof, and & (&A is the same value as the pointer you get when you use A). This also means that you see the array as an array only when you use the name it was declared with, which is only valid in the scope where it is declared. Everywhere else what you have can only be the array name converted to a pointer.
(*) Hmm... did I just say that avariable is a constant? Yes I did. But then they also introduced "const" for other uses...
Warning: unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
In answer to this:
If I have a function that takes a pointer, I declare it as taking a pointer, not an array. I might change my mind if for instance this:
could be caught at compile time, but that would break compatibility with older code and as far as I know there is no compiler that does so.Code:int fn(int a[10]) { a[100] = 0; /* probably out of bounds */ }
Bookmarks