只要你的結構類型沒有任何填充,有標準它沒有明確支持,但可以推斷出對它非常接近的東西的支持。
給出一個平凡複製的類型T
,有什麼明確允許是其代表性複製到的char
(或unsigned char
)和背部的數組。
沒有要求將數組內容保存在數組本身中。內容可以存儲在一個文件中,並在隨後執行該程序時重新讀取。或者存儲在不同類型的對象中,只要該類型允許。爲此,實現必須允許表示對象,當這些表示不是源自同一運行中的T
類型的對象時。
其結果是,在最起碼,
int main() {
vec v = {1.9f, 2.5f, 3.1f};
float a[3];
assert(sizeof v == sizeof a);
{ char tmp[3 * sizeof(float)];
std::memcpy(tmp, &v, 3 * sizeof(float));
std::memcpy(a, tmp, 3 * sizeof(float)); }
assert(a[0] == v.x);
assert(a[1] == v.y);
assert(a[2] == v.z);
vec u;
{ char tmp[3 * sizeof(float)];
std::memcpy(tmp, a, 3 * sizeof(float));
std::memcpy(&u, tmp, 3 * sizeof(float)); }
assert(u.x == a[0]);
assert(u.y == a[1]);
assert(u.z == a[2]);
}
應該或者失敗在第一assert
,或者通過。對於任何表示失敗的表示而言,創建一個恰好以明確有效的方式提供精確表示的函數是微不足道的,因此它不會失敗。
現在,省略tmp
這裏有點不確定。
std::memcpy
只是重複分配的單個字節,可能已被明確拼寫出來。 =
運算符的語義意味着對於可以複製的類型,a = b;
和{ auto tmp = b; a = tmp; }
是等效的。與a = b; c = d;
和{ auto tmp1 = b; auto tmp2 = d; a = tmp1; c = tmp2; }
相同,依此類推。前者是什麼直接memcpy
呢,後者是什麼兩個memcpy
S通過tmp
做。
另一方面,允許複製進出數組char
可以被理解爲需要實際的數組char
,而不僅僅是它的功能等同物。我個人可能不會擔心,除非我真的遇到了一個使用這種解釋的實現,但是如果你想安全地使用它,你可以引入這樣一個臨時數組,並且驗證你的編譯器能夠優化它走了。
來源
2017-02-04 10:27:28
hvd
相關(或者可能重複):http://stackoverflow.com/questions/37211298/accessing-an-array-as-a-struct-vs-undefined-behavior – Barmar
@Barmar它是同樣的問題中討論的我連接的問題。 –
他們都說這是未定義的行爲。你爲什麼認爲你的情況有什麼不同? – Barmar