2013-05-07 53 views
7

如果我定義了一個具有一定對齊要求的簡單類型,那麼所有類型的std::vector<t>都不應該爲每個單個元素提供對齊應該std :: vector榮譽alignof(value_type)?

請看下面的例子

typedef std::array<double,3> alignas(32) avx_point; 
std::vector<avx_point> x(10); 
assert(!(std::ptrdiff_t(&(x[0]))&31) && // assert that x[0] is 32-byte aligned 
     !(std::ptrdiff_t(&(x[1]))&31)); // assert that x[1] is 32-byte aligned 

我發現,對齊要求,就是靜靜地(無任何警告)由鐺3.2(有或無-stdlib=libc++)侵犯,而GCC 4.8.0發出警告,它忽略std::vector(英特爾編譯器太愚蠢,無法理解alignas,但如果我使用__declspec(align(32)),則它的行爲類似於clang)的模板參數上的屬性。兩者都創建觸發斷言的代碼。

那麼,這是正確的行爲還是一個叮噹(和icpc)的錯誤和gcc的問題?

編輯 回答在意見中提出了一個問題:如果我定義

typedef typename std::aligned_storage<sizeof (avx_point), 
             alignof(avx_point)>::type avx_storage; 

我得到

sizeof (avx_storage) == 32; 
alignof(avx_storage) == 32; 

std::vector<avx_storage>仍然無法對齊第一個元素(因此所有的其他人也)爲叮噹聲和海灣合作委員會(這次沒有警告)。所以顯然存在兩個問題:第一,std::allocator<type>即使對於第一個元素(非法?)也忽略任何對齊要求,其次,沒有填充用於確保後續元素的對齊。

+0

出於興趣,如果你比較'的std ::向量<性病:: aligned_storage <的sizeof(avx_point),32 >>'會發生什麼? – Useless 2013-05-07 17:51:18

回答

3

第一,性病::分配器忽略,即使是第一要素的任何對齊要求(非法?)

我從上分配器的專家很遠,但在我看來,很遺憾這是合法的行爲。更確切地說,分配器可能忽略所請求的對齊。事實上,[allocator.requirements],17.6.3.5/6狀態:

如果與特定的過對準類型相關聯的對準不被支持的分配器,分配器用於該類型的實例 可能會失敗。 分配器也可能會默默地忽略請求的對齊

你可以編寫自己的分配器給你對齊的內存。我在工作之前就已經這樣做了,但不幸的是,出於版權原因,我無法公開代碼:-(我可以說,很明顯的一點是它基於_aligned_malloc_aligned_free(這是微軟的擴展)。你可以谷歌爲「不結盟分配器」和幾個選項上來了,其中之一是

https://gist.github.com/donny-dont/1471329

我強調,我不是這對準分配器的作者,我從來沒有使用過它。上述

更新

對準分配器是爲Visual Studio/Windows,但它可以被用來作爲在其他平臺上實現對準分配器基地。您可以使用posix memalign系列函數或C11函數aligned_alloc

請參閱this的帖子。

+1

標準的邏輯是什麼,以便引入關鍵字'alignas'和'alignof'來讓分配器忽略它們?順便說一句,我有我自己的'aligned_allocator <>',它工作得很好(並沒有任何愚蠢的版權問題)。 – Walter 2013-05-08 12:06:25