平台之间的枚举大小不匹配有潜在危险

时间:2016-08-26 13:29:44

标签: c gcc enums arm sizeof

我正在从Linux x86机器上的工作编译开始将net-snmp移植到ARM平台(ThreadX OS,而不是linux)

现在程序在init_snmp()函数内崩溃,因为在某些时候内存会发生一些可怕的事情。

然后我面对sizeof()所有数据类型,发现enum在Linux x86上是4个字节,在ARM上是1个字节。

这种不匹配是否有可能对内存分配造成严重破坏?尝试将字符串写入内存时,程序崩溃。

如何在ARM上强制枚举为4字节大?

我正在使用gcc arm-none-eabi进行编译

2 个答案:

答案 0 :(得分:7)

  

这种不匹配是否有可能对内存分配造成严重破坏?

哦,是的。

  

如何在ARM上强制枚举为4字节大?

C标准说enum变量可能有几乎任何整数类型,大小和签名是实现定义的。因此,枚举通常是有问题的,特别是在嵌入式系统中。这是C语言的一个已知缺陷。

您可以强制枚举为特定编译器的特定大小,但这只是一个快速的&肮脏的修复。

专业的长期解决方案是重写所有代码,以便在任何地方都不依赖于枚举的大小或签名。

答案 1 :(得分:0)

有一种方法可以克服编译器的界限。此示例提供了一种在需要时更改enum大小的方法。

#include <stdio.h>

enum small_enum {
    a 
};

enum large_enum {
    b = 0x7FFFFFFFFFFFFFFFFF // 2^63-1, you should try 2^31-1
};

int main(){
    printf("%d %d\n", sizeof(enum small_enum), sizeof(enum large_enum));
    return 0;
}

此代码在Windows 8计算机上运行时提供以下输出:4 8。通过为其中一个枚举值指定一个大数字,您强制枚举大于编译器定义的值。将其添加到代码中的示例:

enum my_enum {
    ... //your enums values
    MEM_ALLIGNMENT_OF_THE_ENUM = 0x7FFFFFFF
};