2014-02-13 98 views
4

我試圖初始化一個全局作用域的const變量,它的值正確地進行了字節交換。用ntohl()初始化一個const變量

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

const uint32_t a = ntohl(0x11223344); 

int main(int argc, char const *argv[]) 
{ 
    printf("%08x\n", a); 
    return 0; 
} 

使用gcc失敗,錯誤:初始化器元素不是常量。是的,好吧,所以gcc頭文件將ntohl()定義爲一個函數,或者定義爲「do {...} while(0)」或類似的東西,這些東西在編譯時無法評估。遊民。

有什麼我可以做到的,它會達到同樣的目的嗎?我需要初始化適當的結束值,我希望它是一個全局範圍的const。有沒有什麼辦法可以說服gcc做到這一點,短短的滾動我自己的類似宏的宏?

(順便說一句,我注意到,有鏗鏘再用ntohl()定義,使得它可以在編譯時進行評估。上面的代碼示例工程完全鏗鏘。不幸的是我沒有得到我的編譯器的選擇。)

回答

2

初始化它在main()或使用類似(假設的Linux):

#include <endian.h> 
#if __BYTE_ORDER == __LITTLE_ENDIAN 
const uint32_t a = 0x44332211; 
#else 
const uint32_t a = 0x11223344; 
#endif 

或也許

#include <endian.h> 
#define A_ADDR 0x11223344 
#if __BYTE_ORDER == __LITTLE_ENDIAN 
const uint32_t a = __bswap_constant_32(A_ADDR); 
#else 
const uint32_t a = A_ADDR; 
#endif 
3

節6.7.8 /標準的4讀取

All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

ntohl的調用既不是常量表達式,也不是字符串文字。你不能從這裏到達那裏。

但無論如何全局變量是壞的,我懷疑這可能是一個不成熟的優化。簡單的解決方法是直接在您的代碼中使用表達式,這在大端平臺上完全沒有影響,例如

void foo(void) 
{ 
    const unit32_t a = ntohl(0x11223344); 
    /* ... */ 
} 

更好的是,使用預處理器宏,如在

#define POTRZEBIE ntohl(0x11223344) 

void bar(void) 
{ 
    const unit32_t a = POTRZEBIE; 
    /* ... */ 
} 

在具有自動存儲的變量,所述const限定符意味着單個分配,所以與上述的使用沒有問題。