![](/img/trans.png)
[英]Order between __STDCPP_DEFAULT_NEW_ALIGNMENT__ and alignof(std::max_align_t)
[英]Why does the C++ standard allow std::max_align_t and __STDCPP_DEFAULT_NEW_ALIGNMENT__ to be inconsistent?
在Visual Studio中,編譯64位時:
sizeof(std::max_align_t)
是8 __STDCPP_DEFAULT_NEW_ALIGNMENT__
是16 因此,盡管std::max_align_t
指示new
實現應返回對齊的8字節指針,但是具有16字節對齊要求的分配不會將void* operator new (std::size_t count, std::align_val_t);
稱為void* operator new (std::size_t count, std::align_val_t);
方法,但調用void* operator new (std::size_t count);
(請參閱https://en.cppreference.com/w/cpp/memory/new/operator_new ),並期望它們返回對齊的16字節指針。
因此分配這樣定義的結構:
struct alignas(16) S {double m_value;};
將調用標准運算符new
(不帶std::align_val_t
參數)並期望將其對齊16個字節,而std::max_align_t
僅指定應將其對齊8個字節。
這意味着,當否決new
運算符時,即使8個字節就足夠了,也必須將所有內容至少對齊16個字節。
C ++ 17中有兩層過度對齊類型:擴展和新擴展。 std::max_align_t
定義未擴展的最大對齊方式,而__STDCPP_DEFAULT_NEW_ALIGNMENT__
定義未新擴展的最大對齊方式。
顧名思義,新擴展對齊是關於您分配的內容與new
對齊。
基本上,常規operator new
將返回適用於任何對象的內存,直到新擴展的對齊大小為止。 任何更大的對齊方式都傾向於使用operator new
重載來指定要創建的類型的對齊方式。 當然,有條件地支持,就像一般情況下過度對齊的類型一樣。 operator delete
調用以銷毀與此類類型關聯的內存也是如此。
Visual Studio所說的是,最大對齊方式(不認為過度對齊)為8字節,但由operator new
分配的內存對齊方式為16字節。
這意味着,當否決
new
運算符時,即使8個字節就足夠了,也必須將所有內容至少對齊16個字節。
本質上是。 沒有方法可以要求實現告訴您原始operator new/delete
重載要求什么對齊。
現在,您可以在逐個對象的基礎上重載該對象的operator new
以直接調用特定於路線的operator new
。 但是您不能使編譯器這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.