2014-06-13 110 views
1

我有一個客戶端和服務器之間的接口,客戶端發送(1)一個無符號的值,(2)一個標誌,指示值是否有符號/無符號。然後,服務器會將無符號值轉換爲適當的類型。安全地轉換unsigned和signed int

我後來發現這是實現定義的行爲,我一直在閱讀它,但我似乎無法找到一個完全安全的合適解決方案?我讀過關於類型雙擊,指針轉換和memcpy。

只會使用聯合類型的工作?包含signed和unsigned int的UnionType以及signed/unsigned標誌。對於有符號值,客戶端設置聯合的簽名部分,服務器讀取簽名部分。相同的未簽名部分。還是我完全誤解了一些東西?

問題:我怎麼知道這種情況下針對特定場景的特定行爲,例如,在PPC上的windriver diab?我在如何找到這樣的文檔方面有點遺憾。

+0

除非您遇到使用類似補碼或符號大小的系統,否則我認爲您使用的所有內容都將以同樣的方式定義unsigned-> signed轉換。 – user2357112

+0

當客戶端發送一個無符號值但發送了簽名標誌時應該發生什麼? –

+0

你的代碼如何處理簽名標誌? (因爲C++有一個靜態類型系統,你需要在編譯時指定你的類型) –

回答

0

聯合解決方案將要求您讓客戶端和服務器都使用相同的表示形式,這不是一個好主意。 (例如,big-endian和little-endian系統都很常見)。

你應該以某種方式序列化值。但是,您只需爲每種類型單獨執行此操作。

例如(僞碼)

void send_signed(int32_t x) 
{ 
    send(1, "s"); 
    send(sizeof x, serialized x); 
} 

void send_unsigned(uint32_t x) 
{ 
    send(1, "u"); 
    send(sizeof x, serialized x); 
} 

和接收機;你首先閱讀這個類型。如果它是「s」,那麼你反序列化一個帶符號的int並且與它有關的東西;如果它是「你」,那麼你反序列化一個unsigned int(到一個不同的變量),並用它做一些事情。

+0

用戶需要做什麼關於客戶端和服務器的字節順序? –

+0

如果我們假設排序不是問題,那麼聯盟解決方案會起作用嗎? – polemic

+0

@Matt McNabb,'serialized x'需要什麼?只要發送's'或'u',唯一的要求就是將int x轉換爲'(unsigned int)x',比如說'unsigned int xmit = int whatever'併發送。然後在接收端,如果's'被設置,則'int rcvd =(int)xmit'負責簽名。例如:int xmit = -5678被髮送爲:'11111111111111111110100111010010',當's'被接收時,'int rcvd =(int)xmit'的強制轉換在另一端恢復正確的符號:-5678。還有什麼我失蹤? ('x> 2,147,483,647'這樣的情況是行不通的,但是? –

1

轉換unsignedint只是在形式上存在問題。在實踐中,所有現存的平臺使用二進制補碼錶示,其中unsignedintintunsigned(其在形式上明確定義)完全相反。所以’沒問題。


看一看Wikipedia’s article on the UNIVAC對於其中使用一個’的補表示一個平臺的一個例子,例如對於12位和36位位字。

相關問題