www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - NoScopeStatement violates C compatibility principal.

reply "monarch_dodra" <monarchdodra gmail.com> writes:
I have created before two threads about the weird semantics of 
labeled block statements. In a word: putting a label before a 
block means that block does not create a scope, and the variables 
created inside that scope will "leak" to the outside of said 
scope. I've found this to be problematic on several points:

1. No use case for this
2. You can accidentally break code by placing a label before a 
block (but without meaning to label the actual block)
3. Deviates from C.

What kind of bothers me most is the combination 1 & 3: Why??? 
I've complained about this before, and the answer was: "According 
to spec", but to the question "why are the specs like this", I 
have yet to get an answer.

----------------
The reason I'm bringing this up (again), is that it bit me in the 
ass very recently. According to TDPL:

"If a numeric expression compiles in the C language and also 
compiles in D, its
type will be the same in both languages (note that not all C 
expressions must be
accepted by D)."

Followed by

"Rule 1 makes things just a tad more complicated than they would 
otherwise be, but D overlaps enough with C and C++ to inspire 
people to simply copy and paste entire functions into D programs. 
Now it’s all right if D occasionally refuses to compile certain 
constructs for safety or portability reasons; but if it compiled 
that 2000-line encryption package and ran it with different 
results, life would definitely not be good for the hapless 
victim."

So basically, this is saying "If your C code compiles in D, 
you'll get the same result. I guarantee it :)"

Here's a (reduced) C program:

----
int i = 3;

void main()
{
   {
     int some_condition = 1;
     if ( some_condition )
       goto block_end;

     /* dummy code */
   } block_end:

   {
     int i = 7;
     printf("%i", i);
   }

   printf("%i", i);
}
----
C prints: "70"
D prints: "77"

Oops!

I realize 99% of people don't use goto or labels too much, but 
this doesn't mean it shouldn't be addressed. For me, D has been 
about being a "smooth experience", and this makes so little sense 
to me it infuriates me.

I don't see how this could help anyone, but I do see how it can 
create bugs, and these kinds of cases are what D strives to 
avoid. "Fixing" would probably break nothing.

-------------------
I'd like to make a push to get the specs changed in regards to 
this. I'd like to get others' opinion on the matter, in 
particular, if anybody can think of a rationale for the current 
behavior. And if there is no rationale, how much support there is 
for changing it. (in which case I'll file the corresponding ER).
May 28 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
monarch_dodra:

 So basically, this is saying "If your C code compiles in D, 
 you'll get the same result. I guarantee it :)"
It's a general rule, but it has some exceptions, like C programs that rely on global floating point variables initialized to 0, or when you use a fixed-sized array, that D passes by value and C by pointer.
 Here's a (reduced) C program:

 ----
 int i = 3;

 void main()
 {
   {
     int some_condition = 1;
     if ( some_condition )
       goto block_end;

     /* dummy code */
   } block_end:

   {
     int i = 7;
     printf("%i", i);
   }

   printf("%i", i);
 }
 ----
 C prints: "70"
 D prints: "77"
This should go in some page that lists the differences between C and D.
 if anybody can think of a rationale for the current behavior. 
 And if there is no rationale, how much support there is for 
 changing it.
It's bad to break C backwards compatibility for free, so if it's not useful for D then and it should be fixed. Bye, bearophile
May 28 2013
prev sibling parent reply Kenji Hara <k.hara.pg gmail.com> writes:
I think this is a corner case bug of current dmd parser.

Kenji Hara


2013/5/28 monarch_dodra <monarchdodra gmail.com>

 I have created before two threads about the weird semantics of labeled
 block statements. In a word: putting a label before a block means that
 block does not create a scope, and the variables created inside that scop=
e
 will "leak" to the outside of said scope. I've found this to be problemat=
ic
 on several points:

 1. No use case for this
 2. You can accidentally break code by placing a label before a block (but
 without meaning to label the actual block)
 3. Deviates from C.

 What kind of bothers me most is the combination 1 & 3: Why??? I've
 complained about this before, and the answer was: "According to spec", bu=
t
 to the question "why are the specs like this", I have yet to get an answe=
r.
 ----------------
 The reason I'm bringing this up (again), is that it bit me in the ass ver=
y
 recently. According to TDPL:

 "If a numeric expression compiles in the C language and also compiles in
 D, its
 type will be the same in both languages (note that not all C expressions
 must be
 accepted by D)."

 Followed by

 "Rule 1 makes things just a tad more complicated than they would otherwis=
e
 be, but D overlaps enough with C and C++ to inspire people to simply copy
 and paste entire functions into D programs. Now it=E2=80=99s all right if=
D
 occasionally refuses to compile certain constructs for safety or
 portability reasons; but if it compiled that 2000-line encryption package
 and ran it with different results, life would definitely not be good for
 the hapless victim."

 So basically, this is saying "If your C code compiles in D, you'll get th=
e
 same result. I guarantee it :)"

 Here's a (reduced) C program:

 ----
 int i =3D 3;

 void main()
 {
   {
     int some_condition =3D 1;
     if ( some_condition )
       goto block_end;

     /* dummy code */
   } block_end:

   {
     int i =3D 7;
     printf("%i", i);
   }

   printf("%i", i);
 }
 ----
 C prints: "70"
 D prints: "77"

 Oops!

 I realize 99% of people don't use goto or labels too much, but this
 doesn't mean it shouldn't be addressed. For me, D has been about being a
 "smooth experience", and this makes so little sense to me it infuriates m=
e.
 I don't see how this could help anyone, but I do see how it can create
 bugs, and these kinds of cases are what D strives to avoid. "Fixing" woul=
d
 probably break nothing.

 -------------------
 I'd like to make a push to get the specs changed in regards to this. I'd
 like to get others' opinion on the matter, in particular, if anybody can
 think of a rationale for the current behavior. And if there is no
 rationale, how much support there is for changing it. (in which case I'll
 file the corresponding ER).
May 28 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 28 May 2013 at 16:38:50 UTC, Kenji Hara wrote:
 I think this is a corner case bug of current dmd parser.

 Kenji Hara
It's not a corner case. It's the spec. It's a "LabeledStatement" : "NoScopeStatement" http://dlang.org/statement.html#LabeledStatement I was finally able to track down the original bug report, from really long ago: "Label causes scope to collapse into parent" http://d.puremagic.com/issues/show_bug.cgi?id=199 It was closed as "won't fix" by Walter: http://d.puremagic.com/issues/show_bug.cgi?id=199#c6
 Walter Bright 2008-06-23 17:00:19 PDT

 Since the compiler is behaving according to spec, I don't want 
 to change this because it could break existing code, and there 
 doesn't seem to be a compelling reason to do so.
 Walter Bright 2008-06-23 17:29:31 PDT
 
 The test case behaves as expected, because labels do not 
 introduce a new scope when followed by { }.
I hope I just provided a compelling reason why this is bad behavior. And I don't think we'd break anything)
May 28 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 28 May 2013 at 17:54:32 UTC, monarch_dodra wrote:
 On Tuesday, 28 May 2013 at 16:38:50 UTC, Kenji Hara wrote:
 I think this is a corner case bug of current dmd parser.

 Kenji Hara
It's not a corner case. It's the spec.
EDIT: Well, that or I could be miss-interpreting the spec, along with walter having come to a wrong conclusion about the bug report. I can't say without Walter's input.
May 28 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/28/2013 10:54 AM, monarch_dodra wrote:

 It's not a corner case. It's the spec.

 It's a "LabeledStatement" : "NoScopeStatement"
 http://dlang.org/statement.html#LabeledStatement
It is still a bug because NoScopeStatement does not mean "expand into current scope." It means "do not introduce a scope" and clearly allows blocked statements: NoScopeStatement: ; NonEmptyStatement BlockStatement http://dlang.org/statement.html#NoScopeStatement Ali
May 28 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ali Çehreli:

 It is still a bug because NoScopeStatement does not mean 
 "expand into current scope." It means "do not introduce a 
 scope" and clearly allows blocked statements:

 NoScopeStatement:
     ;
     NonEmptyStatement
     BlockStatement
So we reopen issue 199 or we create a new one? Bye, bearophile
May 29 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 29 May 2013 at 09:51:58 UTC, bearophile wrote:
 Ali Çehreli:

 It is still a bug because NoScopeStatement does not mean 
 "expand into current scope." It means "do not introduce a 
 scope" and clearly allows blocked statements:

 NoScopeStatement:
    ;
    NonEmptyStatement
    BlockStatement
So we reopen issue 199 or we create a new one? Bye, bearophile
I reopened it. Its not a new issue, so I don't think it warrants a new thread. EDIT: I did file this though, which is kind of related: http://d.puremagic.com/issues/show_bug.cgi?id=10199
May 29 2013