Array size discrepancy

C

Charles Turner

Please may someone explain why I see this behaviour?

$ gcc -v
....
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

$ cat test.c
#include <stdio.h>
#include <stdlib.h>

void test(int[]);

int main(void)
{
size_t size = sizeof((int[]){1,2,3,4,5,6});
printf("manifest: %zu\n", size);
test((int[]){1,2,3,4,5,6});
return 0;
}

void test(int argv[])
{
size_t size = sizeof(argv);
printf("function: %zu\n", size);
}

$ gcc test.c
$ ./a.out
manifest: 24
function: 8

How do I find the length of the argument in test() if I'm only
receiving 1/3 of it?

Thank you for your time,
Charles.
 
B

Ben Bacarisse

Charles Turner said:
Please may someone explain why I see this behaviour?
$ cat test.c
#include <stdio.h>
#include <stdlib.h>

void test(int[]);

int main(void)
{
size_t size = sizeof((int[]){1,2,3,4,5,6});
printf("manifest: %zu\n", size);
test((int[]){1,2,3,4,5,6});
return 0;
}

void test(int argv[])
{
size_t size = sizeof(argv);
printf("function: %zu\n", size);
}

$ gcc test.c
$ ./a.out
manifest: 24
function: 8
http://c-faq.com/aryptr/aryparmsize.html

How do I find the length of the argument in test() if I'm only
receiving 1/3 of it?

There is no way to find out -- the usual solution is to pass the size
(well, the number of elements is more common) to the function as another
argument.

You can wrap an array in a struct and it will get passed by copying.
The size will be known in the function, but that's not a very C-like
thing to do. A second method involves passing a pointer to the whole
array but both of these end up fixing the array size. This usually
defeats the whole purpose of wanting to know the size.

Actually, you can pass a pointer to a variably modified array, but that
requires passing the number of elements as another argument anyway:

void test(int n, int (*array_ptr)[n]);

so there is little to be gained. Just add another parameter.
 
L

Lew Pitcher

Please may someone explain why I see this behaviour? [snip]
void test(int argv[])
{
size_t size = sizeof(argv);
printf("function: %zu\n", size);
} [snip]
How do I find the length of the argument in test() if I'm only
receiving 1/3 of it?

Please note: your test() function /does not/ "receive" an array. Instead, it
receives a /pointer/. Your sizeof(argv) gives you the size of an integer
pointer, not the size of integer array which the pointer points to.
 
J

John Bode

Please may someone explain why I see this behaviour?

$ gcc -v
...
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

$ cat test.c
#include <stdio.h>
#include <stdlib.h>

void test(int[]);

int main(void)
{
  size_t size = sizeof((int[]){1,2,3,4,5,6});
  printf("manifest: %zu\n", size);
  test((int[]){1,2,3,4,5,6});
  return 0;

}

void test(int argv[])
{
  size_t size = sizeof(argv);
  printf("function: %zu\n", size);

}

$ gcc test.c
$ ./a.out
manifest: 24
function: 8

How do I find the length of the argument in test() if I'm only
receiving 1/3 of it?

Thank you for your time,
Charles.

From the C language standard (latest draft available at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf), section
6.3.2.1, paragraph 3:

---
Except when it is the operand of the sizeof operator or the unary &
operator, or is a
string literal used to initialize an array, an expression that has
type ‘‘array of type’’ is
converted to an expression with type ‘‘pointer to type’’ that points
to the initial element of
the array object and is not an lvalue. If the array object has
register storage class, the
behavior is undefined.
---

In the call to "test", the expression "(int[]){1,2,3,4,5,6}" has its
type implicitly converted ("decay") from 6-element array of int to
pointer to int; what the function "test" receives is a pointer value,
not an array. In the context of a function parameter declaration,
"int argv[]" is synonymous with "int *argv". From section 6.5.7.3,
paragraph 7:

------------
A declaration of a parameter as ‘‘array of type’’ shall be adjustedto
‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within
the [ and ] of the
array type derivation. If the keyword static also appears within the
[ and ] of the
array type derivation, then for each call to the function, the value
of the corresponding
actual argument shall provide access to the first element of an array
with at least as many
elements as specified by the size expression.
------------

The upshot of all of this is that you cannot pass an array as a
function parameter and have it received as an array type. There are
some ways around this (wrapping the array in a struct type, for
example), but for the most part, if you're passing an array argument
to a function and the function needs to know how big the array is, you
will have to compute the size in the caller and pass it as a separate
parameter.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top