簡體   English   中英

C標准對兩種相同類型的聯合說了什么

[英]What does C standard say about a union of two identical types

是否有可能在任何架構上使用任何編譯器使以下斷言失敗?

union { int x; int y; } u;
u.x = 19;
assert(u.x == u.y);

C99對一個聯合的兩個成員是共享初始字段序列的結構的情況做出特殊保證:

struct X {int a; /* other fields may follow */ };
struct Y {int a; /* other fields may follow */ };
union {X x; Y y;} u;
u.x.a = 19;
assert(u.x.a == u.y.a); // Guaranteed never to fail by 6.5.2.3-5.

6.5.2.3-5:為了簡化聯合的使用,我們做了一個特殊的保證:如果一個聯合包含幾個共享一個共同初始序列的結構(見下文),並且如果聯合對象當前包含這些結構中的一個,那么允許在任何可以看到完整類型的聯合聲明的地方檢查其中任何一個的共同初始部分。 如果對應的成員具有一個或多個初始成員的序列的兼容類型(並且對於位字段,具有相同的寬度),則兩個結構共享共同的初始序列。

但是,我無法為聯盟內的非結構化類型找到可比較的保證。 但這很可能是一個遺漏:如果標准花了一些長度來描述結構類型必然會發生什么,甚至不相同,它應該澄清更簡單的非結構化類型的相同點。

問題中的assert永遠不會在標准C的實現中失敗,因為在分配給ux之后訪問uy需要將ux的字節重新解釋為uy的類型。 由於類型相同,重新解釋產生相同的值。

該要求在C 2011(N1570)6.5.2.3注釋95中注明,其表示它源自第6.2.6節,其涵蓋了類型的表示。 注95說:

如果用於讀取union對象內容的成員與上次用於在對象中存儲值的成員不同,則將值的對象表示的相應部分重新解釋為新類型中的對象表示形式在6.2.6中描述(一個過程有時被稱為''punning'')。 這可能是陷阱表示。

(N1570是一份非正式的草案,但很容易上網 。)

我相信這個問題很難以您期望的方式回答。

據我所知,讀取一個不是最近寫入的union一個字段,是未定義的行為。

因此,用“否”回答是不可能的,因為任何編譯器編寫者都可以自由地專門檢測到這一點,並且如果他們有這種感覺就會讓它失敗。

暫無
暫無

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

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