Array size discrepancy

Discussion in 'C Programming' started by Charles Turner, Sep 21, 2011.

  1. 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.
    Charles Turner, Sep 21, 2011
    #1
    1. Advertising

  2. Charles Turner <> writes:

    > Please may someone explain why I see this behaviour?

    <snip>
    > $ 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.

    --
    Ben.
    Ben Bacarisse, Sep 21, 2011
    #2
    1. Advertising

  3. Charles Turner

    Noob Guest

    Noob, Sep 21, 2011
    #3
  4. Charles Turner

    Lew Pitcher Guest

    On September 21, 2011 08:56, in comp.lang.c, wrote:

    > 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.

    --
    Lew Pitcher
    Master Codewright & JOAT-in-training | Registered Linux User #112576
    Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/
    ---------- Slackware - Because I know what I'm doing. ------
    Lew Pitcher, Sep 21, 2011
    #4
  5. Charles Turner

    John Bode Guest

    On Sep 21, 7:56 am, Charles Turner <> wrote:
    > 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.
    John Bode, Sep 21, 2011
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anand P Paralkar

    Discrepancy in CLB Usage Report

    Anand P Paralkar, Jul 2, 2003, in forum: VHDL
    Replies:
    0
    Views:
    1,026
    Anand P Paralkar
    Jul 2, 2003
  2. Gopal
    Replies:
    4
    Views:
    372
    Dario
    Oct 30, 2003
  3. Paul Carey

    Static Access Discrepancy?

    Paul Carey, Jan 16, 2004, in forum: Java
    Replies:
    1
    Views:
    379
    Jon Skeet
    Jan 16, 2004
  4. Eric
    Replies:
    0
    Views:
    370
  5. Michael Winter

    Discrepancy in Array Addition

    Michael Winter, Oct 29, 2006, in forum: Javascript
    Replies:
    3
    Views:
    79
    Randy Webb
    Oct 31, 2006
Loading...

Share This Page