問題描述
板卡有兩個CPU,ARM+MIPS,同時運行三個系統REE(linux) + TEE(SierraTEE) + SEE(TDS)。TEE跟SEE通過RPC進行通信,有enum成員的結構體信息傳遞會出錯,如下結構體:struct sTag {
enum A;
enum B;
int C;
enum D;
};
問題分析
這是由于SierraTEE和TDS使用的是不同的編譯器,而enum這種結構占用內存的大小只有在編譯的時候由編譯器決定的。顯然這是由于兩個編譯器對于enum的分配內存方式不一致導致的。
gcc編譯選項對此有相關說明:-fshort-enums
Allocate to an enum type only as many bytes as it needs for the declared range of possible
values. Specifically, the enum type will be equivalent to the smallest integer type which
has enough room.
Warning: the -fshort-enums switch causes GCC to generate code that is not binary compatible
with code generated without that switch. Use it to conform to a non-default application
binary interface.
即若指定了-fshort-enums,編譯器會分配滿足需求的內存給enum即可,以節省內存;如:若打開了-fshort-enums,sizeof(struct sTag) = 12;
若不打開-fshort-enums,sizeof(struct sTag) = 16;
問題解決
從根本上,尤其是在不同CPU上要使用相同變量作為參數,更應該避免使用enum,因為其size是不能被確定的。但由于TDS中相關的頭文件定義和API定義早以確定并廣泛使用了,這無法修改。
只要確認兩個編譯器使用相同的分配策略處理enum結構,我們選擇-fno-short-enums,即要求編譯器不要采取節省內存的方式,把沒一個enum變量都分配為int的大小。