2016-12-30 56 views
3

考慮下面的代碼:確定字節順序與htons

#include <stdio.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[]) { 
    uint16_t num = 123; 

    if (htons(num) == num) { 
     printf("big endian\n"); 
    } else { 
     printf("little endian\n"); 
    } 
} 

我不知道該代碼是否適用於檢查字節順序?我已經看到很多問題用各種指針/字符技巧檢查它,但我認爲這更簡單。它假定如果你將一個數字轉換爲網絡字節順序(大端),如果它與原始數字相同,那麼你就是一個大端系統。否則,你在一個小端系統。

這個檢查有假設嗎?或許網絡字節順序並不總是大端,但it seems it is standardised to be so

+0

請注意我沒有大型機器來檢查這個代碼,並試圖模擬這樣的系統被證明是不友好的。 –

+0

如果你想徹底徹底,這裏的假設是字節順序是大端或小端。已經有使用其他字節順序的體系結構(例如,PDP-11存儲32位值0x01020304作爲0x02 0x01 0x04 0x03)。顯然,存儲16位值只有兩種可能性。 –

+0

真正的問題是:你爲什麼在乎呢? 'htons'和朋友們的確切意味着讓用戶不關心永恆。代碼依賴於特定永久性的託管環境通常會因設計而中斷。 – Olaf

回答

2

原則上,C允許的uint16_t表示的位是在任何實現定義的順序,不只是「小」或「大端」。正如所寫的,你的測試只會告訴你htons排列位0,1,3,4,5,6和2,7-15分別不混合它們。

如果遍歷兩個冪的所有冪,並在0..15中找到htons(1<<i)==1<<ii,則可以得出結論,該順序絕對是大端。如果您在0..15中找到htons(1<<i)==1<<(i^8)i,則可以得出小尾數。否則你有一個非常不尋常的代表。

在現實中,奇怪的事情不會發生,你的測試應該是足夠的。

+0

是的,這是我期待的那種併發症,但是正如你所表明的那樣,我並沒有期待它在任何合理的系統中成爲問題。很好的回答,謝謝。 –

6

這足以檢查運行時的字節順序。

在大端系統,htons(以及ntohshtonlntohl)被定義爲無操作,而在小端系統,他們執行字節交換。

編輯:

這也可以使用聯合。下面的檢查可以檢測大小寫字母,以及其他更奇特的字節排序。

#include <stdio.h> 
#include <stdint.h> 

union echeck { 
    uint32_t i; 
    char c[4]; 
} echeck = { .c = { 0x01, 0x02, 0x03, 0x04 } }; 

int main() 
{ 
    if (echeck.i == 0x01020304) { 
     printf("big endian\n"); 
    } else if (echeck.i == 0x04030201) { 
     printf("little endian\n"); 
    } else if (echeck.i == 0x02010403) { 
     printf("pdp endian\n"); 
    } else { 
     printf("other endian\n"); 
    } 
    return 0; 
} 
+0

真棒,我不知道那些函數在大端系統上沒有任何操作,這很有趣。謝謝! –

+0

你真的是指* php * -endian嗎?也許pdp-endian? –

+0

@ R ..是的,這是一個錯字。固定。 – dbush