簡體   English   中英

為什么C ++標准允許std :: max_align_t和__STDCPP_DEFAULT_NEW_ALIGNMENT__不一致?

[英]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個字節。

  • 我想念什么嗎?
  • 這是Visual Studio實現C ++ / STL方式的錯誤嗎?
  • 還是C ++ / STL標准中的錯誤?

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM