什么是“部分重叠的对象”?

发布于 2024-12-02 16:19:17 字数 269 浏览 0 评论 0原文

我刚刚经历了 这个线程,其中之一是

分配给部分重叠对象的结果

我想知道是否有人可以给我定义什么是“部分重叠对象”以及如何创建它的代码示例?

I was just going through all the possible Undefined Behaviours in this thread, and one of them is

The result of assigning to partially overlapping objects

I wondered if anyone could give me a definition of what "partially overlapping objects" are and an example in code of how that could possibly be created?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

喵星人汪星人 2024-12-09 16:19:18

正如其他答案所指出的,工会是安排这一点的最明显的方式。

这是一个更清晰的示例,说明了内置赋值运算符如何可能出现部分重叠的对象。如果不是部分重叠的对象限制,此示例将不会表现出 UB。

union Y {
    int n;
    short s;
};

void test() {
    Y y;
    y.s = 3;     // s is the active member of the union
    y.n = y.s;   // Although it is valid to read .s and then write to .x
                 // changing the active member of the union, .n and .s are
                 // not of the same type and partially overlap
}

即使对于相同类型的对象,您也可能会出现部分重叠。考虑此示例,在不向 X 添加填充的实现中,short 严格大于 char

struct X {
    char c;
    short n;
};

union Y {
    X x;
    short s;
};

void test() {
    Y y;
    y.s = 3;     // s is the active member of the union
    y.x.n = y.s; // Although it is valid to read .s and then write to .x
                 // changing the active member of the union, it may be
                 // that .s and .x.n partially overlap, hence UB.
}

As pointed out in other answers, a union is the most obvious way to arrange this.

This is an even clearer example of how partially overlapping objects might arise with the built in assignment operator. This example would not otherwise exhibit UB if it were not for the partially overlapping object restrictions.

union Y {
    int n;
    short s;
};

void test() {
    Y y;
    y.s = 3;     // s is the active member of the union
    y.n = y.s;   // Although it is valid to read .s and then write to .x
                 // changing the active member of the union, .n and .s are
                 // not of the same type and partially overlap
}

You can get potential partial overlap even with objects of the same type. Consider this example in the case where short is strictly larger than char on an implementation that adds no padding to X.

struct X {
    char c;
    short n;
};

union Y {
    X x;
    short s;
};

void test() {
    Y y;
    y.s = 3;     // s is the active member of the union
    y.x.n = y.s; // Although it is valid to read .s and then write to .x
                 // changing the active member of the union, it may be
                 // that .s and .x.n partially overlap, hence UB.
}
晨与橙与城 2024-12-09 16:19:18

联合 就是一个很好的例子。
您可以创建具有重叠成员的内存结构。

例如(来自 MSDN):

union DATATYPE    // Declare union type
{
    char   ch;
    int    i;
    long   l;
    float  f;
    double d;
} var1;

现在如果您使用分配 char 成员,则所有其他成员都未定义。这是因为它们位于同一内存块,并且您只为其一部分设置了实际值:

DATATYPE blah;
blah.ch = 4;

如果您随后尝试访问 blah.iblah.d< /strong> 或 blah.f 它们将具有未定义的值。 (因为只有第一个字节(即字符)设置了其值)

A union is a good example for that.
You can create a structure of memory with overlapping members.

for example (from MSDN):

union DATATYPE    // Declare union type
{
    char   ch;
    int    i;
    long   l;
    float  f;
    double d;
} var1;

now if you use assign the char member all other member are undefined. That's because they are at the same memory block, and you've only set an actual value to a part of it:

DATATYPE blah;
blah.ch = 4;

If you will then try to access blah.i or blah.d or blah.f they will have an undefined value. (because only first byte, which is a char, had its value set)

往事随风而去 2024-12-09 16:19:18

这是指指针别名的问题,在 C++ 中禁止指针别名,以便编译器更容易优化。可以在此线程中找到对该问题的良好解释

This refers to the problem of pointer aliasing, which is forbidden in C++ to give compilers an easier time optimizing. A good explanation of the problem can be found in this thread

浮萍、无处依 2024-12-09 16:19:18

也许他的意思是严格的别名规则?内存中的对象不应与其他类型的对象重叠。

“严格别名是 C(或 C++)编译器做出的一种假设,即取消引用指向不同类型对象的指针永远不会引用相同的内存位置(即彼此别名。)”

May be he mean a strict aliasing rule? Object in memory should not overlap with object of other type.

"Strict aliasing is an assumption, made by the C (or C++) compiler, that dereferencing pointers to objects of different types will never refer to the same memory location (i.e. alias each other.)"

安人多梦 2024-12-09 16:19:18

典型的示例是使用 memcpy:

char *s = malloc(100);
int i;
for(i=0; i != 100;++i) s[i] = i; /* just populate it with some data */
char *t = s + 10;  /* s and t may overlap since s[10+i] = t[i] */
memcpy(t, s, 20); /* if you are copying at least 10 bytes, there is overlap and the behavior is undefined */

memcpy 是未定义行为的原因是因为没有执行复制所需的算法。在这种情况下,引入了 memmove 作为安全的替代方案。

The canonical example is using memcpy:

char *s = malloc(100);
int i;
for(i=0; i != 100;++i) s[i] = i; /* just populate it with some data */
char *t = s + 10;  /* s and t may overlap since s[10+i] = t[i] */
memcpy(t, s, 20); /* if you are copying at least 10 bytes, there is overlap and the behavior is undefined */

The reason why memcpy is undefined behavior is because there's no required algorithm for performing the copy. In this circumstance, memmove was introduced as a safe alternative.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文