2013-09-05 29 views
1

我已代碼C++ 11:存儲數組,如果我返回後聲明它?

template<std::size_t n> 
static inline constexpr uint32_t mask() noexcept 
{ 
    static_assert(n <= 32, "!"); 
    using list = uint32_t[]; 

    return list{ 
     0x0u, 
     0x1u,  0x3u,  0x7,  0xfu,  0x1fu,  0x3fu,  0x7fu,  0xffu, 
     0x1ffu,  0x3ffu,  0x7ffu,  0xfffu,  0x1fffu,  0x3fffu,  0x7fffu,  0xffffu, 
     0x1ffffu, 0x3ffffu, 0x7ffffu, 0xfffffu, 0x1fffffu, 0x3fffffu, 0x7fffffu, 0xffffffu, 
     0x1ffffffu, 0x3ffffffu, 0x7ffffffu, 0xfffffffu, 0x1fffffffu, 0x3fffffffu, 0x7fffffffu, 0xffffffffu 
    } [ n ]; 
} 

問:其中存儲list數組? (在靜態內存,自動內存或無處存儲)?

+0

這是一個問題,你應該問問你的編譯器,而不是我們。但是,爲什麼要存儲? –

+0

它可能會完全優化並且值將被內聯。 –

回答

4

在一個正常的函數中,它將是一個臨時的,存儲在自動存儲器中。由於n是一個編譯時間常量,因此可以優化它以簡單地返回值,移除數組。

但是,這是constexpr,所以返回值應該在編譯時計算。數組在運行時根本不應該存在。

2

由於n在函數中不能是一個變量,例如,

size_t n; 
std::cin >> n; 

std::cout << mask<n>() << std::endl; 

將無法​​編譯,因爲n不是在編譯時間常數,編譯器會不會需要存儲陣列的。通常,constexpr函數不應該生成除某種常數值之外的任何「代碼」。

我的編譯器似乎不接受這裏發佈的代碼 - 可能是因爲它現在有點古老(這是一個gcc 4.6.3 - 我也嘗試過clang ++,但是它失敗了,因爲它試圖使用4.6.3頭文件,這顯然不是「鏗鏘味」)。

當然,它更容易寫這篇文章:

template<std::size_t n> 
inline constexpr uint32_t mask() noexcept 
{ 
    static_assert(n <= 32, "!"); 

    return (1u << n) -1; 
} 

爲了應付特殊情況,其中n == 32(和避免UB,儘管在大多數archtiectures,上面可能會做正確的事):

template<> 
inline constexpr uint32_t mask<32>() noexcept 
{ 
    return ~0; 
} 
+0

如果n == 32,則您的遮罩導致未定義的行爲。 –

+0

@MikeSeymour&@Kurshid:謝謝,我添加了一個'u'來確保。即使你不得不添加一個額外的'if(n == 32)return 0xffffffff',我會說這是比一長串值更好的解決方案。 –

+0

@Mike:這是不明確的。溢出(將左邊的非零高位向外推)將會是,但是移位大於或等於寬度的值仍未定義,即使對於無符號類型。 –