2012-11-14 101 views
2

我正在編寫一個應用程序,我不得不做一些指針算術。然而,這個應用程序將運行在不同的架構上!我不確定這是否會有問題,但在閱讀this article後,我認爲我必須改變它。指針算術和可移植性

這裏是我的原代碼,我不喜歡太多:

class Frame{ 
    /* ... */ 
protected: 
    const u_char* const m_pLayerHeader; // Where header of this layer starts 
    int m_iHeaderLength;    // Length of the header of this layer 
    int m_iFrameLength;     // Header + payloads length 
}; 

/** 
* Get the pointer to the payload of the current layer 
* @return A pointer to the payload of the current layer 
*/ 
const u_char* Frame::getPayload() const 
{ 
    // FIXME : Pointer arithmetic, portability! 
    return m_pLayerHeader + m_iHeaderLength; 
} 

非常糟糕的是吧!將int值添加到u_char指針!但後來我改成這樣:

const u_char* Frame::getPayload() const 
{ 
    return &m_pLayerHeader[m_iHeaderLength]; 
} 

我想現在編譯器能夠說多少跳!對?數組上的操作[]被視爲指針算術?它是否解決了可移植性問題?

+0

你能否更詳細地解釋你的問題?兩個表達式都將始終返回相同的結果。你唯一需要確定的是m_iHeaderLength的含義。只要這是字符,u_chars或字節,你的代碼就可以工作。 – Axel

+0

問題在於可以在不同架構上更改的u_char的大小。我主要是害怕,如果我做「m_pLayerHeader + 1」我去兩個單元格進一步或u_char陣列中的一半單元取決於平臺... – morandg

+1

你會去sizeof(u_char)字節...如果這樣擔心也許使用更多的標準類型(uint8_t)? – avishayp

回答

10

p + i&p[i]是同義詞,當p是指針並且i是整數類型的值。這麼多,你甚至可以寫&i[p],它仍然有效(就像你可以寫i + p一樣)。

您鏈接的示例中的可移植性問題來自sizeof(int),因爲它們跨平臺不同。你的代碼很好,假設m_iHeaderLength是你想要跳過的u_char的數量。

1

在你的代碼中,你正在通過m_iHeaderLength u_chars推進m_pLayerHeader。只要你寫入的數據寫入的數據與u_char具有相同的大小,並且i_HeaderLength是頭部區域中的u_chars的數量,那麼你是安全的。

但是,如果m_iHeaderLength確實指的是字節,而不是u_chars,那麼如果m_iHeaderLength應該使指針超過char以外的其他類型,那麼您可能會遇到問題。

說您是從一個16位的系統,以32位的系統中發送數據,您的首部區域的定義如下

struct Header { 
    int something; 
    int somethingElse; 
}; 

假設是由結構框架所限定的總的消息的唯一部分。

在32位機器上,您將數據寫出到16位機器將從中讀取的端口。

port->write(myPacket, sizeof(Frame)); 

在16位機器上,您具有相同的標題定義,並嘗試讀取信息。

port->read(packetBuffer, sizeof(Frame)); 

您已經遇到了麻煩,因爲您已經嘗試讀取發件人寫入的數據量的兩倍。讀取的16位機器上的int大小爲2,頭部大小爲4。但是發送機上的頭大小是八個,每個四個字節兩個頭。

現在你試圖推進指針

m_iHeaderLength = sizeof(Header); 
... 
packetBuffer += m_iHeaderLength; 

packetBuffer仍將指向這是在從始發者發送的幀標題中的數據。

+0

你能否更詳細地解釋爲什麼如果m_iHeaderLength引用字節數會出現問題? – Axel

+0

@Axel,編輯成包含一個例子。 – Jason

0

如果有一個便攜性問題,則沒有,這不會解決它。 m_pLayerHeader + m_iHeaderLength&m_pLayerHeader[m_iHeaderLength]完全等效(在這種情況下)。

+0

兩個*不相等的情況是什麼情況? – avishayp

+0

m_pLayerHeader + 1是否會轉到所有架構上的u_char陣列中的下一個單元? – morandg

+0

@morandg是... –