[Issue 16708] New: opAssign and struct-member padding break comparison and invariants
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Mon Nov 21 05:51:13 PST 2016
https://issues.dlang.org/show_bug.cgi?id=16708
Issue ID: 16708
Summary: opAssign and struct-member padding break comparison
and invariants
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: major
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: tomerfiliba at gmail.com
When a struct defines an opAssign it is obviously "on its own", but it can't
possibly assign to the padding (which is something built-in assignment does).
Suppose you get the memory for the struct from a memory-pool and you assign a
value to it directly. The memory was uninitialized at first, but there are no
destructors involved, so there's nothing inherently wrong. Here's an example:
========================================================
import std.stdio;
struct MyShort {
ushort value;
void opAssign(MyShort rhs) nothrow @safe @nogc {
value = rhs.value;
}
}
struct YourStruct {
MyShort a;
int b;
}
void main() {
YourStruct ys1;
YourStruct ys2;
(cast(ubyte*)&ys2)[0 .. YourStruct.sizeof] = 0xff;
writeln("ys1=", (cast(ubyte*)&ys1)[0 .. YourStruct.sizeof]);
writeln("ys2=", (cast(ubyte*)&ys2)[0 .. YourStruct.sizeof]);
// ys1=[0, 0, 0, 0, 0, 0, 0, 0]
// ys2=[255, 255, 255, 255, 255, 255, 255, 255]
ys1 = YourStruct(MyShort(17), 18);
ys2 = YourStruct(MyShort(17), 18);
writeln("ys1=", (cast(ubyte*)&ys1)[0 .. YourStruct.sizeof]);
writeln("ys2=", (cast(ubyte*)&ys2)[0 .. YourStruct.sizeof]);
// ys1=[17, 0, 0, 0, 18, 0, 0, 0]
// ys2=[17, 0, 255, 255, 18, 0, 0, 0] <<< does not assign the padding
writeln(ys1.a == ys2.a); // true
writeln(ys1.b == ys2.b); // true
writeln(ys1 == ys2); // false
}
========================================================
So here we get two variables for which memcmp returns != 0, but all their
fields are equal.
--
More information about the Digitalmars-d-bugs
mailing list