Skip to content

Instantly share code, notes, and snippets.

@alifarazz
Last active July 16, 2024 21:47
Show Gist options
  • Save alifarazz/3add33e6605e74c603b03318b8d003df to your computer and use it in GitHub Desktop.
Save alifarazz/3add33e6605e74c603b03318b8d003df to your computer and use it in GitHub Desktop.
Strict Aliasing and restrict key word examples
#include <cstdio>
int f(int *ap, float *bp) {
*ap = 1;
*bp = 2.0f;
return *ap;
}
int main() {
int a = 0; float b = 0.0f;
int r = f(&a, &b);
std::printf("r: %d\n", r);
return 0;
}
// prints 1
#include <cstdio>
int f(int *ap, float *bp) {
*ap = 1;
*bp = 2.0f;
return *ap;
}
int main() {
int a = 0;
int r = f(&a, (float*)&a);
std::printf("r: %d\n", r);
return 0;
}
// prints 1 but should print 2
// https://godbolt.org/z/KrhWahTWE
// https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
typedef struct Msg
{
unsigned int a;
unsigned int b;
} Msg;
void SendWord(uint32_t);
int main(void)
{
// Get a 32-bit buffer from the system
uint32_t* buff = malloc(sizeof(Msg));
// Alias that buffer through message
Msg* msg = (Msg*)(buff);
// Send a bunch of messages
for (int i = 0; i < 10; ++i)
{
msg->a = i;
msg->b = i+1;
SendWord(buff[0]);
SendWord(buff[1]);
}
}
#include <cstdio>
struct A a { int _; }
struct B b { int _; }
int f(struct A *ap, struct B *bp) {
ap->_ = 1;
bp->_ = 2;
return ap->_;
}
int main() {
struct A a = {._ = 0}; struct B b = {._ = 0};
int r = f(&a, &b);
std::printf("r: %d\n", r);
return 0;
}
// prints 1 but should print 2
#include <cstdio>
int f(int *ap, int *bp) {
*ap = 1;
*bp = 2;
return *ap;
}
int g(int * __restrict ap, int * __restrict bp) {
*ap = 1;
*bp = 2;
return *ap;
}
int main() {
int a = 0;
int r1 = f(&a, &a);
int r2 = g(&a, &a);
std::printf("r1: %d\n", r1);
std::printf("r2: %d\n", r2);
return 0;
}
// compile with -fno-strict-aliasing
#include <cstdio>
int f(int *ap, float *bp) {
*ap = 1;
*bp = 2.0f;
return *ap;
}
int main() {
int a = 0;
int r = f(&a, &(float*)a);
std::printf("r: %d\n", r);
return 0;
}
#include <inttypes.h>
#include <stdio.h>
typedef struct {
unsigned int a;
unsigned int b;
} Msg;
extern void SendWord(uint32_t);
int main(void)
{
// Get a 32-bit buffer from the system
uint32_t* buff = malloc(1000 * sizeof(Msg));
memset(s, 0, 1000 * sizeof(Msg)); // init buffer
// Alias that buffer through message
Msg* msg = (Msg*)(buff);
// Send a bunch of messages
for (int i = 0; i < 10; ++i)
{
msg->a = i;
msg->b = i+1;
SendWord(msg->a);
SendWord(msg->b);
}
for (int i = 0; i < 20; i++)
printf("%d\n", buff[i]);
return 0;
}
#include <inttypes.h>
#include <stdio.h>
typedef struct {
unsigned int a;
unsigned int b;
} Msg;
extern void SendWord(uint32_t);
int main(void)
{
// Get a 32-bit buffer from the system
char* buff = malloc(1000 * sizeof(Msg));
memset(s, 0, 1000 * sizeof(Msg)); // init buffer
// Alias that buffer through message
Msg* msg = (Msg*)(buff);
// Send a bunch of messages
for (int i = 0; i < 10; ++i)
{
msg->a = i;
msg->b = i+1;
SendWord(msg->a);
SendWord(msg->b);
}
for (int i = 0; i < 20 * 4; i++) {
printf("%d\n", buff[i]);
}
return 0;
}
#include <stdio.h>
typedef union {
int i; float f;
} convert_float_int_t; // conflicts with POSIX naming... too bad!
float convert_int_to_float_UB(int* a) {
return *(float*)a;
}
float convert_int_to_float(int* a) {
convert_float_int_t converter = {.i = *a};
return converter.b;
}
int main() {
int a = 0x100000F;
float b = convert_int_to_float(&a);
printf("%.32f\n", b);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment