簡體   English   中英

聯合類型的數組可以強制轉換為活動類型的指針嗎?

[英]Can an array of a union type be cast to a pointer of the active type?

給定某種union類型的數組,如果滿足以下條件:

  • 數組中每個union的活動成員是相同的,
  • union每個成員的sizeof相同,並且
  • alignof所述內的每個成員union是相同的
  • (可能)聯合滿足StandardLayoutType的要求

那么以下操作是安全的:

  1. 將此數組轉換為活動類型的指針(目的是將其作為活動類型的數組尋址)
  2. 除了上述數​​組的第一個元素外,還處理其他任何內容?
  3. 假設1和2是可能的; 這對非標准布局類型有效嗎?

例如,考慮以下代碼段:

template<typename T, typename U>
union storage_type
{
    T value0;
    U value1;
};

static_assert( sizeof(int) == sizeof(float), "" );
static_assert( alignof(int) == alignof(float), "" );

storage_type<int,float> storage[] = { {1}, {2}, {3} };

// the active type of all storage_type is 'int', so cast to int*
// to be treated as an array of ints

auto* array = reinterpret_cast<int*>(&storage[0]);

assert( array[0] == 1 );
assert( array[1] == 2 );
assert( array[2] == 3 );

我對C ++標准必須明確說明的這種情況感興趣。 我知道StandardLayoutType可以安全地強制轉換到結構的第一個成員或聯合的活動元素,因此我懷疑我的第一個強制轉換是安全的。 但是我不確定這是否適用於數組,並將其視為活動類型的數組。

我嘗試在SO和C ++標准(N4660 C ++ 17草案)中進行一些搜索-但我沒有運氣

注意 :此問題不是關於由於具有C兼容性的編譯器而在實踐中是否可行; 這是一個嚴格的問題,它是否在C ++中調用UB,以及它是否違反嚴格混疊規則。

從理論上講,這可能會失敗。 按照標准:

聯合的大小足以容納其最大的數據成員。

因此,理論上,sizeof(my_union)和sizeof(largest_member)可能有所不同。

如果您static_assert()相同,則:

int* array = &storage[0].value0;

...做到了,而且由於數組索引的工作原理,您沒有UB的麻煩。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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