sizeof operator shows wrong size of struct in c

Viewed 143

Having this simple code:

#include <stdio.h>

typedef struct
{
    int a;
    char c;
} foo;

void func(void *arg)
{
    printf("sizeof arg: %ld\n", sizeof(*arg));
}

int main()
{
    foo f = {6, 'c'};
    func(&f);

    printf("the real sizeof struct foo: %ld\n", sizeof(f));
}

output:

sizeof arg: 1
the real sizeof struct foo: 8

As you can see the function shows wrong result. If the reason is invalid application of ‘sizeof’ to incomplete type, then why does it shows sizeof arg: 1? void is not 1 bytes long, but incomplete type, so why is this result?

3 Answers

You're attempting to get the size of void which the C standard doesn't allow. However, some implementations define sizeof(void) to be 1 which is what you're seeing here.

The function has no way of knowing that the void * you passed it is actually a foo *. You would need some other way of conveying that information.

This statement

printf("sizeof arg: %ld\n", sizeof(*arg));

is incorrect. The expression *arg has the incomplete type void. You need to write

printf("sizeof arg: %ld\n", sizeof(* ( foo * )arg));

Early versions of C do not have the type void. Instead the type char was used as the type void. As the sizeof( char ) is always equal to 1 then some compilers for backward compatibility with the old specifications of C set sizeof( void ) to 1 though it is not correct from the C Standard's point of view.

The result should be a diagnostic, as sizeof (void) (which sizeof (*arg) resolves to) is a constraint violation:

6.5.3.4 The sizeof and _Alignof operators

Constraints

1    The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member. The _Alignof operator shall not be applied to a function type or an incomplete type.
C 2011 Online Draft

void is an incomplete type that cannot be completed - you cannot create an object that type, so using sizeof on it is a coding error, full stop.

However, for some reason, certain implementations decided to have sizeof (void) evaluate to 1 unless you're in "pedantic" mode. Obviously someone thought it was useful in some circumstances, but I wouldn't recommend its use.

Related