1. 程式人生 > >GCC版本不同導致程式執行結果迥異

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;
}