Tag: 别名

严格别名并通过char *写入int

在一个旧程序中,我将数据结构序列化为字节,通过分配一个unsigned char数组,然后通过以下方式转换为int: *((*int)p) = value; (其中p是unsigned char* , value是要存储的值)。 这工作正常,除非在Sparc上编译,因为访问内存时出现exception对齐而引发exception。 这是完全合理的,因为数据元素具有不同的大小,因此p很快变得不对齐,并在用于存储int值时触发错误,其中底层Sparc指令需要对齐。 这很快得到修复(通过逐字节写出char-array的值)。 但我对此有点担心,因为多年来我在许多程序中都使用过这种结构而没有问题。 但显然我违反了一些C规则(严格别名?),虽然很容易发现这种情况,但是由于优化编译器等原因,违规可能导致其他类型的未定义行为更加微妙。我也有点疑惑,因为我相信多年来我在很多C代码中都看到了这样的结构。 我正在考虑硬件驱动程序,它描述了由硬件交换的数据结构(当然使用pack(1)),并将它们写入h / w寄存器等。所以它似乎是一种常见的技术。 所以我的问题是,上面违反了什么规则,以及实现用例的正确C方法(即将数据序列化为unsigned char数组)。 当然,可以为所有函数编写自定义序列化函数,以逐字节写出它,但听起来很麻烦而且效率不高。 最后,通常可以通过违反此别名规则来预期不良影响(对齐问题等)?

使用GCC / binutils对符号进行别名工作是间歇性的

我正在开发一些有限时间运行裸机的软件,直到Linux端口准备好进入黄金时段。 该软件正在与uClibc链接,uClibc提供了malloc,clock_gettime等的实现,但问题是它们都依赖于系统调用,因为我们还没有内核来处理它们,因此只会陷阱硬件。 我一直在使用别名来覆盖我们需要的函数,即our_mem.c: void* our_malloc(size_t size) { .. } void* malloc(size_t size) __attribute__ ((malloc, weak, alias(“our_malloc”))); 问题是,这似乎有点随机。 我可以有一个构建,其中所有调用都是正确的别名,在下一个构建中,我在一个不相关的文件中修改了它,它突然工作到一个点,然后其中一个调用转到uClibc malloc。 起初我认为这是链接顺序的问题,但构建系统始终以相同的顺序链接,同一个调用将在一个构建中工作,并在下一个构建中失败。 二进制文件(显然)是静态链接的。 我不确定这究竟是如何使用别名的,因为我没有找到很多关于它的文档但我几年前在malloc和朋友(也使用uClibc)上成功使用了这种技术然后它一直工作。

使用指向结构的别名数组,而不违反标准

阅读本文我理解你可以使用别名结构(不违反标准),如果它们具有兼容的成员,即给定以下结构: typedef struct { uint32_t a; uint32_t b; } Frizzly; 以下将破坏别名规则: uint32_t foo(uint16_t *i) { Frizzly *f = (Frizzly *)i; return f->a; } 但以下不会: uint32_t foo(uint32_t *i) { Frizzly *f = (Frizzly *)i; return f->b; } 因为所讨论的“聚合类型”包含与我们投入其中的指针兼容的类型,即类型为uint32_t的指针可以被转换为包含uint32_t类型的成员(或成员)的结构,而不会破坏别名规则。 首先,我是否理解正确? 其次,结构中(其他)变量的排序和类型是否重要? Frizzly说,如果Frizzly被定义如下: typedef struct { uint16_t b[2]; uint32_t a; } 在第二个示例中进行uint32_t , b现在由不兼容( uint32_t )类型的内存支持。 转换是否仍然有效(或者更确切地说,通过转换指针访问值)? 是否会改变i的第一个元素的值(另一种方式) […]

如何投射sockaddr_storage并避免违反严格别名规则

我正在使用Beej的网络指南,并遇到了一个别名问题。 他提出了一个函数来返回特定结构的IPv4或IPv6地址: 1 void *get_in_addr( struct sockaddr *sa ) 2 { 3 if (sa->sa_family == AF_INET) 4 return &(((struct sockaddr_in*)sa)->sin_addr); 5 else 6 return &(((struct sockaddr_in6*)sa)->sin6_addr); 7 } 这会导致GCC为第3行的sa吐出严格别名错误。据我所知,这是因为我这样调用这个函数: struct sockaddr_storage their_addr; … inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), connection_name, sizeof connection_name); 我猜测别名与their_addr变量的类型为sockaddr_storage并且另一个不同类型的指针指向同一内存的事实有关。 是解决这个问题的最佳方法sockaddr_storage , sockaddr_in和sockaddr_in6成为一个联盟? 看起来这应该是网络中的磨损领域,我只是找不到任何有最佳实践的好例子。 此外,如果有人能够准确解释别名问题发生的位置,我会非常感激。

嵌套结构和c中的严格别名

请考虑以下代码: typedef struct { int type; } object_t; typedef struct { object_t object; int age; } person_t; int age(object_t *object) { if (object->type == PERSON) { return ((person_t *)object)->age; } else { return 0; } } 这是合法代码还是违反了C99严格别名规则? 请解释为何合法/非法。

在Windows PowerShell中为GCC设置别名

我正在尝试在Windows PowerShell中设置一个“gcc99”别名,它等于“gcc -std = C99 -pedantic -Wall”。 我们的想法是使用更少的击键来确保GCC以c99模式运行。 (我已尽力使以下post中的指南适应Windows PowerShell: 在GCC中设置std = c99标志 ) 当我在设置这样的别名(下面的图1)后尝试编译时,我收到一个错误。 作为参考,如果我使用扩展命令进行编译,我不会收到此错误(参见下面的图2)。 作为测试,我尝试将gc99设置为“gcc”的别名(没有其他值)并且它工作正常(参见下面的3)。 请忽略我在代码中尚未解决的许多警告:) 有什么建议? (我不确定为什么我的字幕没有出现在下面的图片中。我正在使用自动创建的图片格式,例如,对于第一张图片:“ 标题 ”后面跟着“ 1 :链接”下一行。)