Thread overview
comma operator
Mar 10, 2008
Sivo Schilling
Mar 10, 2008
Derek Parnell
Mar 10, 2008
Sivo Schilling
March 10, 2008
In C/C++ comma operator allows grouping two statements where one is expected.

Example (C/C++):
-------
#include <stdio.h>

int validate(int pos)
{
    return (--pos <= 0 || --pos <= 0), pos;
}

void main()
{
  printf("validate(1) gives %d\n", validate(1));
  printf("validate(2) gives %d\n", validate(2));
  printf("validate(10) gives %d\n", validate(10));
}
-------
Output:
validate(1) gives 0
validate(2) gives 0
validate(10) gives 8

The example above now in D (DMD 1.x/2.x):
-------
import std.stdio;

int validate(int pos)
{
    return (--pos <= 0 || --pos <= 0), pos;
}

void main()
{
  writefln("validate(1) gives ", validate(1));
  writefln("validate(2) gives ", validate(2));
  writefln("validate(10) gives ", validate(10));
}
-------
Output:
validate(1) gives 1
validate(2) gives 2
validate(10) gives 10

Is this expected behaviour or if there's something I've missed ? Any suggestions ?

Regards, Sivo.
March 10, 2008
"Sivo Schilling" <i-b-p@gmx.net> wrote in message news:fr3o34$sc7$1@digitalmars.com...
> In C/C++ comma operator allows grouping two statements where one is expected.
>
> Example (C/C++):
> -------
> #include <stdio.h>
>
> int validate(int pos)
> {
>    return (--pos <= 0 || --pos <= 0), pos;
> }
>
> void main()
> {
>  printf("validate(1) gives %d\n", validate(1));
>  printf("validate(2) gives %d\n", validate(2));
>  printf("validate(10) gives %d\n", validate(10));
> }
> -------
> Output:
> validate(1) gives 0
> validate(2) gives 0
> validate(10) gives 8
>
> The example above now in D (DMD 1.x/2.x):
> -------
> import std.stdio;
>
> int validate(int pos)
> {
>    return (--pos <= 0 || --pos <= 0), pos;
> }
>
> void main()
> {
>  writefln("validate(1) gives ", validate(1));
>  writefln("validate(2) gives ", validate(2));
>  writefln("validate(10) gives ", validate(10));
> }
> -------
> Output:
> validate(1) gives 1
> validate(2) gives 2
> validate(10) gives 10
>
> Is this expected behaviour or if there's something I've missed ? Any suggestions ?
>
> Regards, Sivo.

It seems like a compiler bug.  See, the first part of the comma expression has to be evaluatable as a statement, but you'll notice that if you write:

--pos <= 0 || --pos <= 0;

The compiler will give an error since the second part of the || is not a statement.  If you change it to:

--pos <= 0 || --pos;

It works, since --pos can exist on its own.  Similarly, if you change your function to:

return (--pos <= 0 || --pos), pos;

It works just like the C/C++ version.

The compiler should detect that the first part of the comma expression is not a valid statement and should issue an error to that effect, as it does when it's used on its own.

What's weird is that if you look at the disassembly of the buggy version of the function, the compiler never even outputs code for the first part of the comma expression.  It's almost exactly as if you wrote:

int validate(int pos)
{
    return pos;
}


March 10, 2008
On Mon, 10 Mar 2008 12:36:52 -0400, Sivo Schilling wrote:

> In C/C++ comma operator allows grouping two statements where one is expected.
> 
> Example (C/C++):
> -------
> #include <stdio.h>
> 
> int validate(int pos)
> {
>     return (--pos <= 0 || --pos <= 0), pos;
> }
> 
> void main()
> {
>   printf("validate(1) gives %d\n", validate(1));
>   printf("validate(2) gives %d\n", validate(2));
>   printf("validate(10) gives %d\n", validate(10));
> }
> -------
> Output:
> validate(1) gives 0
> validate(2) gives 0
> validate(10) gives 8
> 

Excuse me for butting in and please don't take this the wrong way, but would one write obscure or idiomatic code like this example, instead of making the code plainly FO to any future maintainer?

I admit that I'm not actually sure what your code is trying to achieve, but I've tried to make a more obvious implementation below. So, why are the functions below a poorer implementation of your code?

int validate(int pos)
{
    if (pos <= 2)
        return 0;
    else
        return pos - 2;
}

And if you *must* have only a single line return ...

int validate(int pos)
{
   return (pos <= 2 ? 0 : pos - 2);
}



-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
March 10, 2008
Hi Derek,

the code snippet you've seen is a simplified excerpt of a more complex
type of return statements in an existing C++ toolkit, which i try to convert to the D programming language.
I agree that the way you are suggested could be gone, but nevertheless its's a litte bit annoying that well known solutions from very old C-times
(and i lived with C during the past twenty vears) could not be D'ed as
expected.

Derek Parnell Wrote:

> On Mon, 10 Mar 2008 12:36:52 -0400, Sivo Schilling wrote:
> 
> > In C/C++ comma operator allows grouping two statements where one is expected.
> > 
> > Example (C/C++):
> > -------
> > #include <stdio.h>
> > 
> > int validate(int pos)
> > {
> >     return (--pos <= 0 || --pos <= 0), pos;
> > }
> > 
> > void main()
> > {
> >   printf("validate(1) gives %d\n", validate(1));
> >   printf("validate(2) gives %d\n", validate(2));
> >   printf("validate(10) gives %d\n", validate(10));
> > }
> > -------
> > Output:
> > validate(1) gives 0
> > validate(2) gives 0
> > validate(10) gives 8
> > 
> 
> Excuse me for butting in and please don't take this the wrong way, but would one write obscure or idiomatic code like this example, instead of making the code plainly FO to any future maintainer?
> 
> I admit that I'm not actually sure what your code is trying to achieve, but I've tried to make a more obvious implementation below. So, why are the functions below a poorer implementation of your code?
> 
> int validate(int pos)
> {
>     if (pos <= 2)
>         return 0;
>     else
>         return pos - 2;
> }
> 
> And if you *must* have only a single line return ...
> 
> int validate(int pos)
> {
>    return (pos <= 2 ? 0 : pos - 2);
> }
> 
> 
> 
> -- 
> Derek Parnell
> Melbourne, Australia
> skype: derek.j.parnell