GCC版本不同導致程式執行結果迥異
之前執行正常的一段程式碼,在升級了編譯工具鏈後出現異常,最後發現是gcc的版本不同,導致編譯出來的程式碼執行結果迥異。如下的程式碼為根據這個問題寫的一段簡單的測試程式。src指向一段資料,此段資料為長度+內容的組合(第一個位元組為長度,其後為此長度的內容)。
unsigned char get_length(unsigned char **src_p)
{
unsigned char ret = **src_p;
(*src_p)++;
return ret;
}
int main(void)
{
unsigned char data[] = {0x01, 0x1, 0x2, 0x3, 0x4};
unsigned char *src = data;
src += get_length(&src);
return 0;
}
說一下前提條件:src的第一個長度位元組為0x01,get_length函式返回1。引起歧義的是這句程式碼:src += get_length(&src)。其中有兩個意義:
1)src指標最終+1。等式左側的src忽略get_length函式內部的++操作,src加上get_lengthh函式返回值1。
2)src指標最終+2。src指標現在get_length內部加1,返回之後在加上get_length的返回值1。
根據gcc版本不同,以上的兩者結果都可能出現。
在CentOS 7.3上測試,gcc版本為4.8.5,為第一種情況 1),src最終增加1。
$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
$ gcc -v
gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
$
在Ubuntu 16.10系統上測試,gcc版本為7.2.0,為第二種情況 2),src最終增加2。
$ cat /etc/issue
Ubuntu 16.10 \n \l
$ gcc -v
gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3)
$
為保證程式碼的相容性,main函式改成如下形式:
int main(void)
{
unsigned char data[] = {0x01, 0x1, 0x2, 0x3, 0x4};
unsigned char *src = data;
int len;
len = get_length(&src);
src += len;
return 0;
}