I am aware that not all types alias with each other in c. You cannot write to an address with an lvalue of one type, then read from it via an lvalue of another type.
My question is if same system applies to const
and non-const
objects.
Example:
char func(char *a, const char *b)
{
*a = '0';
return *b;//undefined behavior?
}
int main()
{
char a = 5;
return (int)func(&a, &a);
}
What matters is the so-called effective type of the original object, which most of the time is the declared type of the object, in this case char a;
. And how you access that one by de-referencing a pointer to it, a so called "lvalue access". *b
would be a "lvalue expression" since the result of the *
operator is an "lvalue" (which basically means: an object allocated at an address).
C23 6.5.1 states:
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 character type.
The above is often called the "strict aliasing rule". From that we can learn:
char*
de-referenced is a type compatible with the effective type of the object (char
in this case). So *a = 0
is fine.const char*
de-referenced is a qualified version of that, const
is a type qualifier. So *b
is fine too.So yes, both pointers in your function alias, since one is the qualified version of the other. And besides they would also alias anyway, if at least one of them was a character pointer.
There is no undefined behavior in your code.