digitalmars.D - NoScopeStatement violates C compatibility principal.
- monarch_dodra (66/66) May 28 2013 I have created before two threads about the weird semantics of
- bearophile (11/36) May 28 2013 It's a general rule, but it has some exceptions, like C programs
- Kenji Hara (13/76) May 28 2013 I think this is a corner case bug of current dmd parser.
- monarch_dodra (12/22) May 28 2013 It's not a corner case. It's the spec.
- monarch_dodra (5/10) May 28 2013 EDIT: Well, that or I could be miss-interpreting the spec, along
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (10/13) May 28 2013 It is still a bug because NoScopeStatement does not mean "expand into
- bearophile (4/11) May 29 2013 So we reopen issue 199 or we create a new one?
- monarch_dodra (5/17) May 29 2013 I reopened it. Its not a new issue, so I don't think it warrants
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
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
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=ewill "leak" to the outside of said scope. I've found this to be problemat=icon 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=tto 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=yrecently. 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=ebe, 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=Doccasionally 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=esame 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=dprobably 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
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 HaraIt'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#c6Walter 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
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: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.I think this is a corner case bug of current dmd parser. Kenji HaraIt's not a corner case. It's the spec.
May 28 2013
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#LabeledStatementIt 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
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 BlockStatementSo we reopen issue 199 or we create a new one? Bye, bearophile
May 29 2013
On Wednesday, 29 May 2013 at 09:51:58 UTC, bearophile wrote:Ali Çehreli: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=10199It 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 BlockStatementSo we reopen issue 199 or we create a new one? Bye, bearophile
May 29 2013