Arrow operator placement C

Viewed 90

Using this example struct:

typedef struct
{
    uint8_t ary[2];
    uint32_t val;
}test_t;

These two code snippets are functionally equivalent:

Snip 1 (arrow operation inside sizeof bracket):

int main()
{
    printf("Hello World");
    printf("\n %d", sizeof(((test_t *)0)->ary));

    return 0;
}

Snip 2 (arrow operation outside sizeof brackets):

int main()
{
    printf("Hello World");
    printf("\n %d", sizeof((test_t *)0)->ary);

    return 0;
}

Both report the correct value if the size of ary is changed however I do not understand how the outside bracket example works as:

sizeof((test_t *)0) // Using memory address 0 as pointer to test_t. size of pointer should be 4 on 32 bit system

Therefore the outside arrow operation in snip 2 should be equivalent to:

4->ary or *4.ary

So why does snip 2 compile and run the same as snip 1

Expected output: 2
1 Answers

Quote from N1570 6.5.3 Unary operators:

Syntax
1   unary-expression:
    postfix-expression
        ++ unary-expression
        -- unary-expression
        unary-operator cast-expression
        sizeof unary-expression
        sizeof ( type-name )
        _Alignof ( type-name )

As you see, the sizeof operator that takes expression doesn't require parenthesis.

Therefore both sizeof(((test_t *)0)->ary) and sizeof((test_t *)0)->ary are valid.

Note that printf("\n %d", sizeof(((test_t *)0)->ary)); is invalid (invokes undefined behavior) because wrong format specifier is used. %d is for printing int. sizeof operator returns size_t and the format specifier for that is %zu.

Related