1

I understand why an array decays to a pointer when passed to a function without specifying its size, eg.:

void test(int array[]);

Why does it do so when passed with the size? eg.

void test(int array[3]);

I am having trouble with sizeof under the latter function signature, which is frustrating as the array length is clearly known at compile time.

5
  • 4
    That is just how the language is defined (and has been for a very long time) - either pass the size as a separate parameter, or embed the array in a struct, or switch to a different language. Commented Oct 8, 2017 at 8:25
  • 1
    Because that's how it was designed. We could give you a history lesson, but it wouldn't help you much. Commented Oct 8, 2017 at 8:26
  • 2
    It's an optimization on behalf of the language designers. One could certainly agree with them, or consider it premature in retrospect. But that's how the language is designed. Commented Oct 8, 2017 at 8:35
  • I really hate the usage of "An array decays to a pointer". I'd say it's more accurate to say "An array decays to an address." An array is a region of memory - it exists. It has an address - a valid address that can't be changed, nor assigned to. (You can't assign to an address - you can assign to the memory the address refers to.) A pointer, on the other hand, is a variable (another memory location) that can contain an address, which may or may not be valid. Commented Oct 8, 2017 at 17:42
  • I guess my point is, why bother allowing the latter syntax if the compiler is just going to ignore the provided size? Commented Oct 9, 2017 at 2:52

2 Answers 2

3
void test(int* array);
void test(int array[]);
void test(int array[3]);

All these variants are the same. C just lets you use alternative spellings but even the last variant explicitly annotated with an array size decays to a pointer to the first element.

That is, even with the last implementation you could call the function with an array of any size:

void test(char str[10]) { }

test("test"); // Works.
test("let's try something longer"); // Still works.

There is no magic solution, the most readable way to handle the problem is to either make a struct with the array + the size or simply pass the size as an additional parameter to the function.

LE: Please note that this conversion only applies to the first dimension of an array. When passed to a function, an int[3][3] gets converted to an int (*)[3], not int **.

Sign up to request clarification or add additional context in comments.

2 Comments

So int array[3] is more for the programmer's benefit than anything else?
In my opinion, it shouldn't be used. It might give the user a false sense of security (“oh, this function only accepts an array of length 3 so I don’t need to check the length myself”)
1

Because you would not be able to call such a function properly. In almost all contexts an array decays to a pointer to the first element, and at any attempt to call the function an array would first be converted to a pointer and the call would be a mismatch. The only contexts where an array does not decay are the operators sizeof, _Alignof, _Alignas and &. These are easier to detect syntactically.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.