Thread overview
DMD 0.164: Possible bug in order of evaluation
Aug 18, 2006
Klaus Oberhofer
Aug 18, 2006
Stewart Gordon
Aug 20, 2006
Walter Bright
Aug 21, 2006
Klaus Oberhofer
August 18, 2006
While porting some C-Code to D I had a possible bug that has to do with the order of evaluation of the post increment operator. The following C sample

<c-code>
#include <memory.h>
#include <stdio.h>

void main()
{
  unsigned short testarray_a[17];
  unsigned short testarray_b[17];

  unsigned short start  = 0;

  int i;

  memset(testarray_a, 0, sizeof(testarray_a));
  memset(testarray_b, 0, sizeof(testarray_a));

  i = start;
  while (i <= 16)
  {
    testarray_a[i] = 1U << (16 - i);
    i++;
  }

  i = start;
  while (i <= 16)
  {
    testarray_b[i++] = 1U << (16 - i);
  }

  printf("a:");
  for (i = 1; i <= 16; i++)
    printf("%i ", testarray_a[i]);
  printf("\n");

  printf("b:");
  for (i = 1; i <= 16; i++)
    printf("%i ", testarray_b[i]);
  printf("\n");
}
</c-code>

compiled with DMC and VC7 creates the following output:

a:32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1 b:32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1

An equivalent D code

<d-code>
module testarray.main;

void main()
{
  ushort testarray_a[17];
  ushort testarray_b[17];

  int i;
  ushort start = 0;

  i = start;
  while (i <= 16)
  {
    testarray_a[i] = 1U << (16 - i);
    i++;
  }

  i = start;
  while (i <= 16)
  {
    testarray_b[i++] = 1U << (16 - i);
  }

  printf("a:");
  for (i = 1; i <= 16; i++)
    printf("%i ", testarray_a[i]);
  printf("\n");

  printf("b:");
  for (i = 1; i <= 16; i++)
    printf("%i ", testarray_b[i]);
  printf("\n");
}
</d-code>

compiled with DMD 0.164 produces:

a:32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1 b:16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1 0

Could someone confirm this as a bug ?
August 18, 2006
Klaus Oberhofer wrote:

> While porting some C-Code to D I had a possible bug that has to do with the order of evaluation of the post increment operator. 
<snip>
> Could someone confirm this as a bug ?

No.

http://www.digitalmars.com/d/expression.html

"Evaluation Order

Unless otherwise specified, the implementation is free to evaluate the components of an expression in any order. It is an error to depend on order of evaluation when it is not specified. For example, the following are illegal:

i = ++i;
c = a + (a = b);
func(++i, ++i);

If the compiler can determine that the result of an expression is illegally dependent on the order of evaluation, it can issue an error (but is not required to). The ability to detect these kinds of errors is a quality of implementation issue."

Stewart.
August 20, 2006
Klaus Oberhofer wrote:
> While porting some C-Code to D I had a possible bug that has to do with the order of evaluation of the post increment operator. The following C sample
[...]
>     testarray_b[i++] = 1U << (16 - i);
[...]
> Could someone confirm this as a bug ?

In the source code, yes. Depending on order of evaluation of side effects is an error in D as well as an error in C and C++.
August 21, 2006
Walter Bright <newshound@digitalmars.com> wrote in news:eca93v$ddt$1 @digitaldaemon.com:

> Klaus Oberhofer wrote:
>> While porting some C-Code to D I had a possible bug that has to do with the order of evaluation of the post increment operator. The following C sample
> [...]
>>     testarray_b[i++] = 1U << (16 - i);
> [...]
>> Could someone confirm this as a bug ?
> 
> In the source code, yes. Depending on order of evaluation of side effects is an error in D as well as an error in C and C++.
> 

Thank you for the lesson, Walter :)

Under normal circumstances I stay away from such constructs like the devil
from holy water. But I converted parts of unarj.c to D, and this
wonderful piece of code is a good example for your recently proposed
new D coding style :)
My failure was, that I tried to stay away from the internals of unarj.
Never mind, I'm here to learn and this way I learn much about D and
as a side effect about the internals of dictionary coders.
Greets

Klaus


BTW, one of my C books states that ANSI C compliant compilers are not
allowed to move/discard code unless they can prove there are no
side effects. It further says that on non compliant compilers the behaviour
is undefined.