Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
Let's analyze this code, assuming an architecture where the alignment of int64_t is the same as that of double: void bar(double *f, int64_t *j) { *(int64_t *)f = *j; } void foo(void) ...
#11: Post edited
- Let's analyze this code, assuming an architecture where the alignment of `int64_t` is the same as that of `double`:
- ```c
- void
- bar(double *f, int64_t *j)
- {
- *(int64_t *)f = *j;
- }
- void
- foo(void)
- {
- int64_t i = 1;
- bar((double *) &i, &i);
- }
- ```
- - The object is of type `int64_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?- Does this code have Defined Behavior?
- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness in `bar()` by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
- Let's analyze this code, assuming an architecture where the alignment of `int64_t` is the same as that of `double`:
- ```c
- void
- bar(double *f, int64_t *j)
- {
- *(int64_t *)f = *j;
- }
- void
- foo(void)
- {
- int64_t i = 1;
- bar((double *) &i, &i);
- }
- ```
- - The object is of type `int64_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only see the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Does this code have Defined Behavior?
- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness in `bar()` by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
#9: Post edited
Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:- ```c
- void
bar(float *f, int32_t *j)- {
*(int32_t *)f = *j;- }
- void
- foo(void)
- {
int32_t i = 1;bar((float *) &i, &i);- }
- ```
- The object is of type `int32_t`.- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Does this code have Defined Behavior?
- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness in `bar()` by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
- Let's analyze this code, assuming an architecture where the alignment of `int64_t` is the same as that of `double`:
- ```c
- void
- bar(double *f, int64_t *j)
- {
- *(int64_t *)f = *j;
- }
- void
- foo(void)
- {
- int64_t i = 1;
- bar((double *) &i, &i);
- }
- ```
- - The object is of type `int64_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Does this code have Defined Behavior?
- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness in `bar()` by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
#8: Post edited
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i = 1;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
Is this code snippet Defined Behavior?- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness in `bar()` by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i = 1;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Does this code have Defined Behavior?
- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness in `bar()` by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
#7: Post edited
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i = 1;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- To be clear, there are two doubts in that code:
- Is there an implicit `restrict`ness by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i = 1;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness in `bar()` by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
#6: Post edited
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i = 1;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i = 1;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- To be clear, there are two doubts in that code:
- - Is there an implicit `restrict`ness by the fact that the pointers are pointers to incompatible types, even if I didn't use the qualifier?
- - Is it valid to convert a pointer back to its real type before dereferencing, or is that information lost in the function boundary?
#5: Post edited
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
int32_t i;- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i = 1;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
#4: Post edited
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i;
bar((float *) &i, i);- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i;
- bar((float *) &i, &i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
#3: Post edited
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i;
- bar((float *) &i, i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
However, how does this play with `restrict` and the strict aliasing rules, and assumptions that compilers may make?- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i;
- bar((float *) &i, i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` (which I didn't use on purpose) and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
#2: Post edited
Let's analyze this function, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i;
- bar((float *) &i, i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
- Let's analyze this code, assuming an architecture where the alignment of `int32_t` is the same as that of `float`:
- ```c
- void
- bar(float *f, int32_t *j)
- {
- *(int32_t *)f = *j;
- }
- void
- foo(void)
- {
- int32_t i;
- bar((float *) &i, i);
- }
- ```
- - The object is of type `int32_t`.
- - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7:
- <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7>
- - It's converted back to the actual type of the object, before it's dereferenced.
- However, how does this play with `restrict` and the strict aliasing rules, and assumptions that compilers may make?
- Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they?
- Is this code snippet Defined Behavior?
#1: Initial revision
Strict aliasing rules and function boundaries
Let's analyze this function, assuming an architecture where the alignment of `int32_t` is the same as that of `float`: ```c void bar(float *f, int32_t *j) { *(int32_t *)f = *j; } void foo(void) { int32_t i; bar((float *) &i, i); } ``` - The object is of type `int32_t`. - The pointer is stored as a pointer to a different object type, but that's allowed by C11::6.3.2.3/7: <https://port70.net/%7Ensz/c/c11/n1570.html#6.3.2.3p7> - It's converted back to the actual type of the object, before it's dereferenced. However, how does this play with `restrict` and the strict aliasing rules, and assumptions that compilers may make? Assuming that `bar()` is defined in a different Translation Unit, the compiler will only wee the parameters. With that information, it doesn't know that the real type is correctly accessed, so what can it do? Also, AFAIK, compilers interpret this function prototype so that `f` and `j` can not alias, don't they? Is this code snippet Defined Behavior?