md5
md5

Reputation: 23699

About generic pointer to char and strict aliasing

I don't know why the following code works fine, without gcc errors (-fstrict-aliasing -Wstrict-aliasing=1).

#include <stdio.h>

int 
main(void) 
{
    char  n = 42;
    char *p = &n;
    int  *q = (int *)p;

    *q = 10;

    printf("%d|%d\n", *p, *q);

    return 0;
}

If I follow the strict aliasing rule:

n1570, § 6.5 Expressions

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

— a type compatible with the effective type of the object,

— a qualified version of a type compatible with the effective type of the object,

— a type that is the signed or unsigned type corresponding to the effective type of the object,

— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,

— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or

— a character type.

But *q does not have a type compatible with *p, either a qualified version, either a signed or unsigned type corresponding, either a character type.

So, why is it allowed?

Upvotes: 2

Views: 238

Answers (1)

2501
2501

Reputation: 25752

It is not allowed. The part of the Standard you posted shows through what types are you allowed to alias objects.

The fact that the code compiled doesn't mean it is correct. You are having three problems with the code that make it the program exhibit undefined behavior.

First is that you assigned a char pointer to an int pointer. Standard doesn't enforce their alignment and representation, so the resulting pointer is not valid.

int  *q = (int *)p;

Then you interpreted the char n object as an integer, violating strict aliasing.( Note the quote from the Standard in your question ).

*q;

Finally you wrote an int into the memory of the char object (char n), which causes an overflow because the size of an int is always larger than size of a char.

*q = 10;

Upvotes: 3

Related Questions