www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Goto skips declaration

reply Michelle Long <HappyDance321 gmail.com> writes:
This should not be an error when the goto jumps outside the 
current block!

{
    goto Y;
    int x;
}
Y:

There is no chance of any local variable being used. This makes 
it impossible to use goto statements in any reasonable way 
without littering the code with brackets.
Oct 28 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 29/10/2018 4:22 PM, Michelle Long wrote:
 This should not be an error when the goto jumps outside the current block!
 
 {
     goto Y;
     int x;
 }
 Y:
 
 There is no chance of any local variable being used. This makes it 
 impossible to use goto statements in any reasonable way without 
 littering the code with brackets.
 
Compiles + runs: import std.stdio; void main() { { goto Y; int x; writeln("booo", x); } Y: writeln("Hello D"); } Going to need a more complete example.
Oct 28 2018
parent reply Bauss <jj_1337 live.dk> writes:
On Monday, 29 October 2018 at 03:24:35 UTC, rikki cattermole 
wrote:
 On 29/10/2018 4:22 PM, Michelle Long wrote:
 This should not be an error when the goto jumps outside the 
 current block!
 
 {
     goto Y;
     int x;
 }
 Y:
 
 There is no chance of any local variable being used. This 
 makes it impossible to use goto statements in any reasonable 
 way without littering the code with brackets.
 
Compiles + runs: import std.stdio; void main() { { goto Y; int x; writeln("booo", x); } Y: writeln("Hello D"); } Going to need a more complete example.
The problem is when you remove the brackets. OP I don't see what you expect the compiler to do? You're skipping the declaration and usage of it so what's the point? D is not Javascript and has no concept of hoisting.
Oct 29 2018
next sibling parent reply Michelle Long <HappyDance321 gmail.com> writes:
On Tuesday, 30 October 2018 at 06:37:22 UTC, Bauss wrote:
 On Monday, 29 October 2018 at 03:24:35 UTC, rikki cattermole 
 wrote:
 On 29/10/2018 4:22 PM, Michelle Long wrote:
 This should not be an error when the goto jumps outside the 
 current block!
 
 {
     goto Y;
     int x;
 }
 Y:
 
 There is no chance of any local variable being used. This 
 makes it impossible to use goto statements in any reasonable 
 way without littering the code with brackets.
 
Compiles + runs: import std.stdio; void main() { { goto Y; int x; writeln("booo", x); } Y: writeln("Hello D"); } Going to need a more complete example.
The problem is when you remove the brackets. OP I don't see what you expect the compiler to do? You're skipping the declaration and usage of it so what's the point? D is not Javascript and has no concept of hoisting.
You take examples WAY to literal. Sheesh, do you really think life is that simple? Do you need every detail spelled out for things to make sense? foreach(x; Y) { if (something or another which I won't spell out no matter how much you cry) goto Q; // compiler complains here about x int x; } Q: There is no reason why the compiler should have a problem with this.. the fact that using brackets around int x; satisfies the compiler proves this.
Oct 30 2018
next sibling parent Dennis <dkorpel gmail.com> writes:
On Tuesday, 30 October 2018 at 21:21:22 UTC, Michelle Long wrote:
 There is no reason why the compiler should have a problem with 
 this.. the fact that using brackets around int x; satisfies the 
 compiler proves this.
It doesn't have a problem with that? https://run.dlang.io/is/YRapyT Also, if you're jumping out of a scope, most of the time a (labeled) break suffices. I suppose in your actual code, you skip to somewhere further than the first statement after the current block?
Oct 30 2018
prev sibling parent reply luckoverthere <luckoverthere gmail.cm> writes:
On Tuesday, 30 October 2018 at 21:21:22 UTC, Michelle Long wrote:
 You take examples WAY to literal. Sheesh, do you really think 
 life is that simple? Do you need every detail spelled out for 
 things to make sense?

 foreach(x; Y)
 {
     if (something or another which I won't spell out no matter 
 how much you cry)
         goto Q; // compiler complains here about x
     int x;
 }
 Q:

 There is no reason why the compiler should have a problem with 
 this.. the fact that using brackets around int x; satisfies the 
 compiler proves this.
struct Magic { ~Magic() { writeln("blah"); } ] void test() { if(cond) goto Y; Magic magic; Y: writeln("stuff"); // calls ~Magic(); } You'd need a bunch of extra information to know what is and wasn't actually declared and initialized. "Putting brackets around it proves it". void test() { if(cond) goto Y; { Magic magic; // calls ~Magic(); } Y: writeln("stuff"); } There is no more conflict with brackets, yes. But expecting the compiler to do this changes the behavior of the code. Sure if there's no destructor it could work around it, but it would complicated code generation. Adding a bunch of time looking for these circumstances. It's just not worth it, use brackets like you are now or move the declarations of your variables up to the top of the scope before any gotos. Pretty simple workarounds.
Oct 30 2018
parent reply Michelle Long <HappyDance321 gmail.com> writes:
On Tuesday, 30 October 2018 at 23:31:46 UTC, luckoverthere wrote:
 On Tuesday, 30 October 2018 at 21:21:22 UTC, Michelle Long 
 wrote:
 You take examples WAY to literal. Sheesh, do you really think 
 life is that simple? Do you need every detail spelled out for 
 things to make sense?

 foreach(x; Y)
 {
     if (something or another which I won't spell out no matter 
 how much you cry)
         goto Q; // compiler complains here about x
     int x;
 }
 Q:

 There is no reason why the compiler should have a problem with 
 this.. the fact that using brackets around int x; satisfies 
 the compiler proves this.
struct Magic { ~Magic() { writeln("blah"); } ] void test() { if(cond) goto Y; Magic magic; Y: writeln("stuff"); // calls ~Magic(); } You'd need a bunch of extra information to know what is and wasn't actually declared and initialized. "Putting brackets around it proves it". void test() { if(cond) goto Y; { Magic magic; // calls ~Magic(); } Y: writeln("stuff"); } There is no more conflict with brackets, yes. But expecting the compiler to do this changes the behavior of the code. Sure if there's no destructor it could work around it, but it would complicated code generation. Adding a bunch of time looking for these circumstances. It's just not worth it, use brackets like you are now or move the declarations of your variables up to the top of the scope before any gotos. Pretty simple workarounds.
You are not understanding the problem. The goto must be in the same scope as the local variable: { goto Y; int x; } Y: The compiler will complain(I'm doing it in a foreach loop) that x is skipped!!! Do you understand? The goto will always bypass x being declared so it doesn't matter. The compiler may optimize out the simple case above, but that is irrelevant to the problem. The problem is simple: The compiler thinks that the declared variables are used after the goto but it is impossible since the goto skips out of the block and the local variables cease to exist. The compiler treats the problem as if it is { goto Y: int x; Y: } and that is a totally different problem. They are not the same but the compiler treats them the same. In the second case the goto does skip over the declaration, in the first case it does not. In the second case it is a problem but in the first case it cannot be. Again, adding the brackets proves it.
Nov 02 2018
parent reply Rubn <where is.this> writes:
On Saturday, 3 November 2018 at 03:52:12 UTC, Michelle Long wrote:
 On Tuesday, 30 October 2018 at 23:31:46 UTC, luckoverthere 
 wrote:
 On Tuesday, 30 October 2018 at 21:21:22 UTC, Michelle Long 
 wrote:
 You take examples WAY to literal. Sheesh, do you really think 
 life is that simple? Do you need every detail spelled out for 
 things to make sense?

 foreach(x; Y)
 {
     if (something or another which I won't spell out no 
 matter how much you cry)
         goto Q; // compiler complains here about x
     int x;
 }
 Q:

 There is no reason why the compiler should have a problem 
 with this.. the fact that using brackets around int x; 
 satisfies the compiler proves this.
struct Magic { ~Magic() { writeln("blah"); } ] void test() { if(cond) goto Y; Magic magic; Y: writeln("stuff"); // calls ~Magic(); } You'd need a bunch of extra information to know what is and wasn't actually declared and initialized. "Putting brackets around it proves it". void test() { if(cond) goto Y; { Magic magic; // calls ~Magic(); } Y: writeln("stuff"); } There is no more conflict with brackets, yes. But expecting the compiler to do this changes the behavior of the code. Sure if there's no destructor it could work around it, but it would complicated code generation. Adding a bunch of time looking for these circumstances. It's just not worth it, use brackets like you are now or move the declarations of your variables up to the top of the scope before any gotos. Pretty simple workarounds.
You are not understanding the problem. The goto must be in the same scope as the local variable: { goto Y; int x; } Y: The compiler will complain(I'm doing it in a foreach loop) that x is skipped!!! Do you understand? The goto will always bypass x being declared so it doesn't matter. The compiler may optimize out the simple case above, but that is irrelevant to the problem. The problem is simple: The compiler thinks that the declared variables are used after the goto but it is impossible since the goto skips out of the block and the local variables cease to exist. The compiler treats the problem as if it is { goto Y: int x; Y: } and that is a totally different problem. They are not the same but the compiler treats them the same. In the second case the goto does skip over the declaration, in the first case it does not. In the second case it is a problem but in the first case it cannot be. Again, adding the brackets proves it.
The problem you describe doesn't exist. https://run.dlang.io/is/Snpt3l If that isn't the issue, then actually give a runable source example with the associated error that it produces.
Nov 03 2018
next sibling parent reply Michelle Long <HappyDance321 gmail.com> writes:
On Saturday, 3 November 2018 at 20:04:40 UTC, Rubn wrote:
 On Saturday, 3 November 2018 at 03:52:12 UTC, Michelle Long 
 wrote:
 On Tuesday, 30 October 2018 at 23:31:46 UTC, luckoverthere 
 wrote:
 On Tuesday, 30 October 2018 at 21:21:22 UTC, Michelle Long 
 wrote:
 You take examples WAY to literal. Sheesh, do you really 
 think life is that simple? Do you need every detail spelled 
 out for things to make sense?

 foreach(x; Y)
 {
     if (something or another which I won't spell out no 
 matter how much you cry)
         goto Q; // compiler complains here about x
     int x;
 }
 Q:

 There is no reason why the compiler should have a problem 
 with this.. the fact that using brackets around int x; 
 satisfies the compiler proves this.
struct Magic { ~Magic() { writeln("blah"); } ] void test() { if(cond) goto Y; Magic magic; Y: writeln("stuff"); // calls ~Magic(); } You'd need a bunch of extra information to know what is and wasn't actually declared and initialized. "Putting brackets around it proves it". void test() { if(cond) goto Y; { Magic magic; // calls ~Magic(); } Y: writeln("stuff"); } There is no more conflict with brackets, yes. But expecting the compiler to do this changes the behavior of the code. Sure if there's no destructor it could work around it, but it would complicated code generation. Adding a bunch of time looking for these circumstances. It's just not worth it, use brackets like you are now or move the declarations of your variables up to the top of the scope before any gotos. Pretty simple workarounds.
You are not understanding the problem. The goto must be in the same scope as the local variable: { goto Y; int x; } Y: The compiler will complain(I'm doing it in a foreach loop) that x is skipped!!! Do you understand? The goto will always bypass x being declared so it doesn't matter. The compiler may optimize out the simple case above, but that is irrelevant to the problem. The problem is simple: The compiler thinks that the declared variables are used after the goto but it is impossible since the goto skips out of the block and the local variables cease to exist. The compiler treats the problem as if it is { goto Y: int x; Y: } and that is a totally different problem. They are not the same but the compiler treats them the same. In the second case the goto does skip over the declaration, in the first case it does not. In the second case it is a problem but in the first case it cannot be. Again, adding the brackets proves it.
The problem you describe doesn't exist. https://run.dlang.io/is/Snpt3l If that isn't the issue, then actually give a runable source example with the associated error that it produces.
No, the problem actually exists. Simply because a simplified example does not produce the result does not mean it doesn't exist. The compiler does a lot of things so to suggest that I simply fabricated the error because the simplified demonstration case does not produce the error as pathetic. I got this error in my code and I simplified all the crap out of it to what I did that produced it and how I remedied it. It's not my fault you don't believe me.
Nov 03 2018
next sibling parent reply lithium iodate <whatdoiknow doesntexist.net> writes:
On Saturday, 3 November 2018 at 21:36:08 UTC, Michelle Long wrote:
 No, the problem actually exists. Simply because a simplified 
 example does not produce the result does not mean it doesn't 
 exist. The compiler does a lot of things so to suggest that I 
 simply fabricated the error because the simplified 
 demonstration case does not produce the error as pathetic.

 I got this error in my code and I simplified all the crap out 
 of it to what I did that produced it and how I remedied it. 
 It's not my fault you don't believe me.
That's simply the to us accessible evidence speaking against you. Check out DustMite if you haven't already, it's a tool for automatically reducing code while maintaining a user-defined condition, such as the equivalence of compiler output. This thread will get nowhere as long as nobody can reproduce the issue.
Nov 03 2018
parent reply Michelle Long <HappyDance321 gmail.com> writes:
On Saturday, 3 November 2018 at 21:55:56 UTC, lithium iodate 
wrote:
 On Saturday, 3 November 2018 at 21:36:08 UTC, Michelle Long 
 wrote:
 No, the problem actually exists. Simply because a simplified 
 example does not produce the result does not mean it doesn't 
 exist. The compiler does a lot of things so to suggest that I 
 simply fabricated the error because the simplified 
 demonstration case does not produce the error as pathetic.

 I got this error in my code and I simplified all the crap out 
 of it to what I did that produced it and how I remedied it. 
 It's not my fault you don't believe me.
That's simply the to us accessible evidence speaking against you. Check out DustMite if you haven't already, it's a tool for automatically reducing code while maintaining a user-defined condition, such as the equivalence of compiler output. This thread will get nowhere as long as nobody can reproduce the issue.
Look, sometimes it is nearly impossible to reduce because the problem is far more complicated... also compilers do a lot of hacky shit like optimization or rewriting things that then hide the error when reduced. To try and act like it is my fault is ridiculous. Dustmite doesn't work. This is typical of dmd where nothing ever works as expected but the core group of people always seem to point fingers and expect the outsiders to deal with the mess they make. Do people here expect me to find all the bugs for D? Also expect me to fix them? Write proper tooling? Where does it end? When can someone just come in and say I've experienced a bug, this is what it `looks` like and then move on? The fact is, I explained the simple case and gave the error. This proves that either DMD has an issue or it has an issue. Building Win32\Debug\Demo.exe... test.d(164): Error: `goto` skips declaration of variable And when I simply wrap what follows in a block it compiles! That is enough to PROVE there is a bug somewhere. Either it is an issue with goto or some other compiler bug or a complex combination of problems, but all due to dmd. The fact that I can't produce a simple test case for others does not disprove this. The example I gave wasn't meant for a test case but to outline the problem. I thought it was a grammar related language decision. Either way, I would expect the "experts" to be able to figure out the real underlying issue immediately or after a few minutes of work. I guess I expect to much? But what happens is the flood of the tyrants who demand that I stop everything I'm doing and produce a test case that has the same bug so they can be convinced that such a bug exists come marching in! It's not like any of them(or almost) will do anything to fix the bug. In fact, many will say it's not a bug but a feature. In fact, given how long it takes for many bugs to get fixed in the D world(on the order of years), it is pointless.
Nov 04 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, November 4, 2018 10:12:37 AM MST Michelle Long via Digitalmars-d 
wrote:
 On Saturday, 3 November 2018 at 21:55:56 UTC, lithium iodate

 wrote:
 On Saturday, 3 November 2018 at 21:36:08 UTC, Michelle Long

 wrote:
 No, the problem actually exists. Simply because a simplified
 example does not produce the result does not mean it doesn't
 exist. The compiler does a lot of things so to suggest that I
 simply fabricated the error because the simplified
 demonstration case does not produce the error as pathetic.

 I got this error in my code and I simplified all the crap out
 of it to what I did that produced it and how I remedied it.
 It's not my fault you don't believe me.
That's simply the to us accessible evidence speaking against you. Check out DustMite if you haven't already, it's a tool for automatically reducing code while maintaining a user-defined condition, such as the equivalence of compiler output. This thread will get nowhere as long as nobody can reproduce the issue.
Look, sometimes it is nearly impossible to reduce because the problem is far more complicated... also compilers do a lot of hacky shit like optimization or rewriting things that then hide the error when reduced. To try and act like it is my fault is ridiculous. Dustmite doesn't work. This is typical of dmd where nothing ever works as expected but the core group of people always seem to point fingers and expect the outsiders to deal with the mess they make. Do people here expect me to find all the bugs for D? Also expect me to fix them? Write proper tooling? Where does it end? When can someone just come in and say I've experienced a bug, this is what it `looks` like and then move on? The fact is, I explained the simple case and gave the error. This proves that either DMD has an issue or it has an issue. Building Win32\Debug\Demo.exe... test.d(164): Error: `goto` skips declaration of variable And when I simply wrap what follows in a block it compiles! That is enough to PROVE there is a bug somewhere. Either it is an issue with goto or some other compiler bug or a complex combination of problems, but all due to dmd. The fact that I can't produce a simple test case for others does not disprove this. The example I gave wasn't meant for a test case but to outline the problem. I thought it was a grammar related language decision. Either way, I would expect the "experts" to be able to figure out the real underlying issue immediately or after a few minutes of work. I guess I expect to much? But what happens is the flood of the tyrants who demand that I stop everything I'm doing and produce a test case that has the same bug so they can be convinced that such a bug exists come marching in! It's not like any of them(or almost) will do anything to fix the bug. In fact, many will say it's not a bug but a feature. In fact, given how long it takes for many bugs to get fixed in the D world(on the order of years), it is pointless.
Not having participated in this thread previously, and looking it over now, it looks to me like there's a definite communication problem in this thread. It's easy to believe that you found a bug in something like this a complicated D program, but when you then give a simplified example and claim it's buggy when that simplified example works, I don't think that it's terribly surprising for folks to then turn around and say that you're wrong about that code not working given that the code that you're showing _does_ work. It's rude if they claim that you're not seeing any bugs in your program, but the way you presented the problem made it seem like you were claiming that the simplified code snippets were broken, when they're not. It's just the more complicated code which is hard to reduce into something simple which is broken. And if you'd been clear about that up front, this conversation probably would not have gotten as hotheaded. But ultimately the problem with a bug like this (and I've hit annoying bugs of my own that are very difficult to turn into simplified test cases) is that unless you are able to provide a test case to the developers, the cold hard reality is that the odds of them being able to do anything about the problem are almost zero. Yes, if they stare at the code long enough, they might be able to figure something out, but they probably won't, and they're likely to just end up wasting their time even if they really, really want to help you. A reproducible test case means a _lot_. And with all of the other bugs that they could be working on which do have reproducible test cases, they're not likely to spend their time on one where pretty much all they have to go on is someone giving them an error message. They _need_ to be able to reproduce the problem themselves. And while it would be great if you could provide something that was no more than a dozen lines of codes, even if the best you can do is provide a 10,000 line module that reproduced the problem in a bug report, at least if you were able to do that, then the developers would have something to work with. But regardless of the length of the example you provide, without a bug report, the developers aren't going to do anything. Please report your issue in bugzilla with the smallest piece of code that you can, even if that piece of code is annoyingly big: https://issues.dlang.org That at least makes it _possible_ for someone to reproduce the problem and try to track it down, whereas right now, no one can help you, because you haven't reported the bug in bugzilla, and you haven't given enough information to reproduce the problem. - Jonathan M Davis
Nov 04 2018
prev sibling parent Rubn <where is.this> writes:
On Sunday, 4 November 2018 at 17:12:37 UTC, Michelle Long wrote:
 That is enough to PROVE there is a bug somewhere. Either it is 
 an issue with goto or some other compiler bug or a complex 
 combination of problems, but all due to dmd.

 The fact that I can't produce a simple test case for others 
 does not disprove this. The example I gave wasn't meant for a 
 test case but to outline the problem. I thought it was a 
 grammar related language decision. Either way, I would expect 
 the "experts" to be able to figure out the real underlying 
 issue immediately or after a few minutes of work. I guess I 
 expect to much?

 But what happens is the flood of the tyrants who demand that I 
 stop everything I'm doing and produce a test case that has the 
 same bug so they can be convinced that such a bug exists come 
 marching in! It's not like any of them(or almost) will do 
 anything to fix the bug. In fact, many will say it's not a bug 
 but a feature.
It's not a matter of convincing someone. Imagine someone told you there's a needle in a haystack and they have magnet to find it, but then they are demanding you find it without a magnet. Without a reproducible test case your error won't be fixed. If you reduced it to it's simplest form and the error doesn't exist anymore, then how is someone suppose to find out what is wrong with it? Problems don't get solved if they can't be reproduced. You have a reproducible test case. If you want it to get fixed the bare minimum you have to do is provide the test case for it. Again not a matter of convincing, but fixing a bug with a test case is 100000x easier than without one.
Nov 04 2018
prev sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Saturday, 3 November 2018 at 21:36:08 UTC, Michelle Long wrote:

 No, the problem actually exists. Simply because a simplified 
 example does not produce the result does not mean it doesn't 
 exist. The compiler does a lot of things so to suggest that I 
 simply fabricated the error because the simplified 
 demonstration case does not produce the error as pathetic.
Why are you so hostile?! No one is suggesting anything of the sort. I'm sure you understand that in order to fix a problem it first needs to be reproduced. There are several issues sitting in Bugzilla that no one can do anything about because they only occur in people's non-trivial codebases.
 I got this error in my code and I simplified all the crap out 
 of it to what I did that produced it and how I remedied it. 
 It's not my fault you don't believe me.
??? The example that you provided is literally shown to work. You insist there is a problem regardless, but no one except you can provide an actual sample case, unless someone else eventually runs into it, of course.
Nov 03 2018
prev sibling parent reply MatheusBN <m gmail.com> writes:
On Saturday, 3 November 2018 at 20:04:40 UTC, Rubn wrote:
 If that isn't the issue, then actually give a runable source 
 example with the associated error that it produces.
I'm not the OP, but I could reproduce! Example 1 - Problem: void main(){ goto Q; int x; Q: writeln("a"); } Error: source_file.d(4): Error: goto skips declaration of variable source.main.x at source_file.d(5) Example 2 - Now if you add brackets: void main(){ { goto Q; int x; } Q: writeln("a"); It will work. MatheusBN.
Nov 04 2018
parent MatheusBN <m gmail.com> writes:
On Sunday, 4 November 2018 at 22:09:31 UTC, MatheusBN wrote:
 I'm not the OP, but I could reproduce!

 Example 1 - Problem:

 void main(){
     goto Q;
     int x;
     Q:
     writeln("a");
 }

 Error: source_file.d(4): Error: goto skips declaration of 
 variable source.main.x at source_file.d(5)


 Example 2 - Now if you add brackets:

 void main(){
     {
         goto Q;
          int x;
     }
     Q:
     writeln("a");


 It will work.

 MatheusBN.
By the way I forgot the link: https://rextester.com/OUJHT98447 MatheusBN
Nov 04 2018
prev sibling next sibling parent programmer <programmer mail.com> writes:
On Tuesday, 30 October 2018 at 06:37:22 UTC, Bauss wrote:
 D is not Javascript and has no concept of hoisting.
Neither is C. -------------- #include <stdio.h> int main() { // In C, depending on your warning settings, you might get // an 'unreachable' code warning when you compile. // D however, treats the code as an 'error', and won't compile it... // unless you add those extra braces. // in my view, it should at most be a 'warning', not an 'error'. // trust the programmer! //{ goto Y; int x; printf("%d",x); //} Y: puts("Hello"); } --------------
Oct 30 2018
prev sibling parent goto-go <goto-go live.com> writes:
On Tuesday, 30 October 2018 at 06:37:22 UTC, Bauss wrote:
 D is not Javascript and has no concept of hoisting.
C is not javascript either... int main() { goto Y; puts("you will not see this"); Y: puts("Hello D"); return 0; } // so.. as first asked, why does D require you to put in extra brackets?
Oct 30 2018
prev sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Monday, 29 October 2018 at 03:22:17 UTC, Michelle Long wrote:
 This should not be an error when the goto jumps outside the 
 current block!
Can you post the entire function where you're seeing this error?
Nov 04 2018