[英]Accessing consecutive members with a single pointer
我想用一個指針訪問連續聲明的相同類型的成員數組。
例如,我說:
struct S
{
double m1[2];
double m2[2];
}
int main()
{
S obj;
double *sp = obj.m1;
// Code that maybe unsafe !!
for (int i(0); i < 4; ++i)
*(sp++) = i; // *
return 0;
}
線(*)在什么情況下有問題?
我知道當存在虛擬函數時肯定會出現問題,但是我需要一個比我的假設更結構化的答案
您可以確定該結構的成員按它們出現的順序存儲在一個連續的字節塊中。 此外,數組的元素是連續的。 因此,似乎一切都很好。
這里的問題是,沒有標准的方法可以知道結構中連續成員之間是否存在填充字節。
因此,假設根本沒有填充字節是不安全的。
如果由於某些特殊原因可以確定沒有填充字節,那么4個double
元素將根據需要是連續的。
C ++標准對“普通舊數據”(或在C ++ 11中為標准布局)類型的布局提供了某些保證。 在大多數情況下,這些繼承自C如何處理此類數據。
以下內容僅適用於“普通舊數據” /“標准布局”結構和數據。
如果您有兩個具有相同初始順序和參數類型的結構,則將指向一個指針的指針轉換為指向另一個指針的指針並訪問它們的公共初始前綴是有效的,並將訪問相應的字段。 這稱為“布局兼容”。 如果您具有結構X和結構Y,並且X是結構Y的第一個元素,則這也適用-可以將指向Y的指針強制轉換為指向X的指針,並且它將訪問X子結構中的字段。 Y.
現在,盡管這是一個普遍的假設,但我沒有意識到C或C ++的要求,即以相同類型和計數的字段開頭的數組和結構必須與數組在布局上兼容。
您的情況有點類似,因為我們在結構中有兩個彼此相鄰的數組,您將其視為一個大數組,其大小等於這兩個數組的總和。 這是一個相對常見且安全的假設,但我不知道該標准會真正起作用。
在這種不確定的行為中,您必須檢查有關原始普通數據/標准布局數據的布局的特定編譯器保證(事實上或顯式),因為C ++標准不保證您的代碼可以執行您想要的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.