使用__attribute__(__packed__)填充结构体是否真的值得?

6
gcc (GCC) 4.7.0
c89
x86_64

你好,

我想知道在结构体上使用__attribute__ ((__packed__))是否值得。据我测试,使用它可以使结构体的大小更小。因此,在大小方面使用它会有优势。

不使用它的原因是它在其他编译器中不具备可移植性,例如在Visual Studio C++中无法使用,其他编译器也一样。

编译器不会对代码进行优化吗?所以让编译器决定如何处理可能更有利于性能?

使用aligned属性会有任何区别吗?__attribute__((packed, aligned(4)))当我添加它时,返回大小为12。

非常感谢您的建议,

#include <stdio.h>

struct padded {
    int age;      /* 4                    */
    char initial; /* 1 + 3 padded bytes   */
    int weight;   /* 4     --> total = 12 */ 
};

struct __attribute__ ((__packed__)) unpadded {
    int age;      /* 4                  */
    char initial; /* 1                  */
    int weight;   /* 4    --> total = 9 */
};

int main(int argc, char **argv)
{
    struct padded padded_test;
    struct unpadded unpadded_test;

    printf("Padded   [ %ld ]\n", sizeof(struct padded));
    printf("Unpadded [ %ld ]\n", sizeof(struct unpadded));
    return 0;
}

4
未对齐的内存访问速度较慢。 - BlackBear
对于您的示例结构,进行打包和4字节对齐特别不值得。您并没有节省任何空间,只是使“weight”字段失去了对齐。唯一的原因是为了匹配以这种方式定义的某些预先存在的布局(即使这假定您知道在您的平台上“int”的对象表示对于“age”字段是正确的)。 - Steve Jessop
2个回答

13

在某些架构(例如ia64、sparc64)上,未对齐的内存访问可能非常缓慢。 __attribute__((__packed__)) 主要用于在通过网络发送数据时确保布局的正确性;在尝试节省内存空间时使用它并不值得。

如果您正在考虑将 __attribute__((__packed__)) 用于网络传输,请再三考虑;它无法处理字节序,并且是非标准的。编写自己的编组代码更加安全,使用库(例如Protocol Buffers)更加明智。


3
你可以 勉强地 使用 __packed__ 传输已定义的格式(例如公共协议),通过像 htonl 这样的方式处理字节序。但即使如此,这样做也几乎没有什么意义,与其编写符合规范的结构体,你可能更好的是显式地编写字段的大小和偏移量。 - Steve Jessop

0

__attribute__((packed)) 的另一个用途是访问内存映射控制器。正如其他人所建议的那样,除了非常特定的事情之外,它并不真正有用。未对齐的访问是不好的,在某些架构上会生成异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接