これが私が思いついた解決策で、データ フィールドへのアクセスにいくつかの代替手段を実装しています。
// #define USE_MEMCPY
// #define USE_PACKED
#ifdef __cplusplus
template <typename T> void SET(T *__attribute__((may_alias)) p, T val) {
*p=val;
}
template <typename T> T GET(T *__attribute__((may_alias)) p) {
return *p;
}
#else
#ifdef USE_MEMCPY
#include <string.h>
#define _SET(p,val,line) \
({ typeof(val) _temp_##line = (val); \
memcpy((void*)(p),(void*)&_temp_##line,sizeof(_temp_##line)); })
#define _GET(p,line) \
({ typeof(*(p)) _temp_##line; \
memcpy((void*)&_temp_##line,(void*)(p),sizeof(_temp_##line)); \
_temp_##line; })
#define SET(p,val) _SET(p,val,__LINE__)
#define GET(p) _GET(p,__LINE__)
#else /* no memcpy */
#ifdef USE_PACKED
#define SET(p,val) (((struct { typeof(val) x __attribute__((packed)); } __attribute__((may_alias))*)p)->x=(val))
#define GET(p) (((struct { typeof(*p) x __attribute__((packed)); } __attribute__((may_alias))*)p)->x)
#else
#define SET(p,val) (*((typeof(val) __attribute__((may_alias))*)p)=(val))
#define GET(p) (*((typeof(*p) __attribute__((may_alias))*)p))
#endif
#endif
#endif
次に、次のように関数を記述できます。
int q(int *p) {
SET(p,GET(p)+12);
return p[0];
}