www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Weird codegen bug

reply RazvanN <razvan.nitu1305 gmail.com> writes:
import std.stdio : writeln;

void main()
{
     int a = 7;
     int b = 9;

     /* some code later */

     *(&a + 1) = 2;
     writeln(b);
     writeln(b);
}

This code prints:

9
2

with latest version of dmd. Is this a bug or am I missing 
something? For the record,
gdc prints (as expected):

2
2
Jun 13
next sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
ldc will print
9
9
and sigsegv :D

On Thu, Jun 13, 2019 at 1:30 PM RazvanN via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 import std.stdio : writeln;

 void main()
 {
      int a = 7;
      int b = 9;

      /* some code later */

      *(&a + 1) = 2;
      writeln(b);
      writeln(b);
 }

 This code prints:

 9
 2

 with latest version of dmd. Is this a bug or am I missing
 something? For the record,
 gdc prints (as expected):

 2
 2
Jun 13
prev sibling next sibling parent Dennis <dkorpel gmail.com> writes:
On Thursday, 13 June 2019 at 11:28:25 UTC, RazvanN wrote:
 Is this a bug or am I missing something? For the record,
 gdc prints (as expected):
What happens is that b lives in a register. After the first call, the register is invalidated and it has to be reloaded with the value on the stack (modified by your pointer). I'm pretty sure *(&a + 1) = 2; is undefined behavior, so both dmd and gdc are correct. (Assembly can be seen here: https://run.dlang.io/is/bjxVXg)
Jun 13
prev sibling next sibling parent Radu <void null.pt> writes:
On Thursday, 13 June 2019 at 11:28:25 UTC, RazvanN wrote:
 import std.stdio : writeln;

 void main()
 {
     int a = 7;
     int b = 9;

     /* some code later */

     *(&a + 1) = 2;
     writeln(b);
     writeln(b);
 }

 This code prints:

 9
 2

 with latest version of dmd. Is this a bug or am I missing 
 something? For the record,
 gdc prints (as expected):

 2
 2
Check out gotbolt output: https://godbolt.org/z/sxo_8l
Jun 13
prev sibling next sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Thursday, 13 June 2019 at 11:28:25 UTC, RazvanN wrote:
 import std.stdio : writeln;

 void main()
 {
     int a = 7;
     int b = 9;

     /* some code later */

     *(&a + 1) = 2;
     writeln(b);
     writeln(b);
 }

 This code prints:

 9
 2

 with latest version of dmd. Is this a bug or am I missing 
 something? For the record,
 gdc prints (as expected):

 2
 2
It's definitely not a codegen bug. It's a programmers assumption bug :-)
Jun 13
prev sibling next sibling parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 13 June 2019 at 11:28:25 UTC, RazvanN wrote:
 import std.stdio : writeln;

 void main()
 {
     int a = 7;
     int b = 9;

     /* some code later */

     *(&a + 1) = 2;
     writeln(b);
     writeln(b);
 }

 This code prints:

 9
 2

 with latest version of dmd. Is this a bug or am I missing 
 something? For the record,
 gdc prints (as expected):

 2
 2
Why would you think this should work? Locals are not the same as struct members, you can't just walk a pointer around.
Jun 13
parent reply RazvanN <razvan.nitu1305 gmail.com> writes:
On Thursday, 13 June 2019 at 13:45:04 UTC, John Colvin wrote:
 On Thursday, 13 June 2019 at 11:28:25 UTC, RazvanN wrote:
 import std.stdio : writeln;

 void main()
 {
     int a = 7;
     int b = 9;

     /* some code later */

     *(&a + 1) = 2;
     writeln(b);
     writeln(b);
 }

 This code prints:

 9
 2

 with latest version of dmd. Is this a bug or am I missing 
 something? For the record,
 gdc prints (as expected):

 2
 2
Why would you think this should work? Locals are not the same as struct members, you can't just walk a pointer around.
I think it's odd that b changes its value for no apparent reason. I understand why it happens, still it is surprising.
Jun 13
parent John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 13 June 2019 at 15:42:38 UTC, RazvanN wrote:
 On Thursday, 13 June 2019 at 13:45:04 UTC, John Colvin wrote:
 On Thursday, 13 June 2019 at 11:28:25 UTC, RazvanN wrote:
 import std.stdio : writeln;

 void main()
 {
     int a = 7;
     int b = 9;

     /* some code later */

     *(&a + 1) = 2;
     writeln(b);
     writeln(b);
 }

 This code prints:

 9
 2

 with latest version of dmd. Is this a bug or am I missing 
 something? For the record,
 gdc prints (as expected):

 2
 2
Why would you think this should work? Locals are not the same as struct members, you can't just walk a pointer around.
I think it's odd that b changes its value for no apparent reason. I understand why it happens, still it is surprising.
Undefined behaviour is often surprising.
Jun 13
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/13/2019 4:28 AM, RazvanN wrote:
 import std.stdio : writeln;
 
 void main()
 {
      int a = 7;
      int b = 9;
 
      /* some code later */
 
      *(&a + 1) = 2;
      writeln(b);
      writeln(b);
 }
 
 This code prints:
 
 9
 2
 
 with latest version of dmd. Is this a bug or am I missing something? For the 
 record,
 gdc prints (as expected):
 
 2
 2
 
It's undefined behavior to access memory beyond the boundaries of the memory object pointed to: https://github.com/dlang/dlang.org/pull/2649/files#diff-2bcc1b9af1e2da4f63bfda4b26f114a2R90 in an update to the spec that nobody sees fit to pull :-(
Jun 14