www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - goto skips declaration of variable

reply "nrgyzer" <nrgyzer gmail.com> writes:
Hi all,

I've the following code snipped:

import std.bigint;
void main(string[] args)
{
	BigInt i = "12345";
	if (args.length > 1)
	{
		goto Exit;
	}
	i = BigInt("67890");
	Exit:
		return;
}

When I try to compile this sample application I'm getting the 
following error:

sample.d(7): Error: goto skips declaration of variable 
sample.main.__ctmp1344 at sample.d(9)

I know that the error is caused by the line 'i = 
BigInt("67890")'. I also know that I can simply replace the 
goto-condition with something like this:

if (args.length == 0)
{
	i = BigInt("67890");
}

But that's not what I want because I've many BigInt-assignments 
in my real application. That would result in a very very deep, 
nested source structure and that really hurts. So, is there any 
solution how I can realize the BigInt-assignment after the 
goto-Command (or better: without skipping the declaration)?
Aug 18 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
nrgyzer:

 import std.bigint;
 void main(string[] args)
 {
 	BigInt i = "12345";
 	if (args.length > 1)
 	{
 		goto Exit;
 	}
 	i = BigInt("67890");
 	Exit:
 		return;
 }

 When I try to compile this sample application I'm getting the 
 following error:

 sample.d(7): Error: goto skips declaration of variable 
 sample.main.__ctmp1344 at sample.d(9)
It looks like a compiler bug (perhaps caused by a rewrite rule). The 'i' variable is declared before the goto. Bye, bearophile
Aug 18 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
 It looks like a compiler bug
https://issues.dlang.org/show_bug.cgi?id=13321 Bye, bearophile
Aug 18 2014
prev sibling next sibling parent reply ollie <ollie home.net> writes:
On Mon, 18 Aug 2014 13:51:12 +0000, nrgyzer wrote:

 When I try to compile this sample application I'm getting the 
 following error:
 
 sample.d(7): Error: goto skips declaration of variable 
 sample.main.__ctmp1344 at sample.d(9)
 
http://dlang.org/changelog.html#disable_goto_skips_init First item in D2.065 Changelog for language changes : 1. Goto jumps now cannot skip variable declarations
Aug 18 2014
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/18/2014 09:07 AM, ollie wrote:
 On Mon, 18 Aug 2014 13:51:12 +0000, nrgyzer wrote:

 When I try to compile this sample application I'm getting the
 following error:

 sample.d(7): Error: goto skips declaration of variable
 sample.main.__ctmp1344 at sample.d(9)
http://dlang.org/changelog.html#disable_goto_skips_init First item in D2.065 Changelog for language changes : 1. Goto jumps now cannot skip variable declarations
So, that is the change that caused this regression. nrgyzer's code does not violate that rule. Ali
Aug 18 2014
prev sibling next sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Mon, 18 Aug 2014 13:51:12 +0000
nrgyzer via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 When I try to compile this sample application I'm getting the=20
 following error:
=20
 sample.d(7): Error: goto skips declaration of variable=20
 sample.main.__ctmp1344 at sample.d(9)
it's compiler bug i believe. but why do you need gotos at the first place? i'm not saying that "you must avoid gotos at all costs!", but D has some nice features like scope(exit), scope(success), scope(failure) and nested functions, which can render gotos unnecessary in many cases (and make code cleaner).
Aug 18 2014
parent reply "nrgyzer" <nrgyzer gmail.com> writes:
On Monday, 18 August 2014 at 17:47:21 UTC, ketmar via 
Digitalmars-d-learn wrote:
 On Mon, 18 Aug 2014 13:51:12 +0000
 nrgyzer via Digitalmars-d-learn 
 <digitalmars-d-learn puremagic.com>
 wrote:

 When I try to compile this sample application I'm getting the 
 following error:
 
 sample.d(7): Error: goto skips declaration of variable 
 sample.main.__ctmp1344 at sample.d(9)
it's compiler bug i believe. but why do you need gotos at the first place? i'm not saying that "you must avoid gotos at all costs!", but D has some nice features like scope(exit), scope(success), scope(failure) and nested functions, which can render gotos unnecessary in many cases (and make code cleaner).
I know, gotos are having a negative connotation. Sure, I can also use nested functions, but in my opinion it results in dirty and complex code. It's totally overkilled compared to a simple if and goto-instruction. The same regards the scoping... it's simply to much overhead.
Aug 19 2014
next sibling parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Tue, 19 Aug 2014 08:04:54 +0000
nrgyzer via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 goto-instruction. The same regards the scoping... it's simply to=20
 much overhead.
it's a matter of taste, i think. i myself find 'scope(exit)' excellent, 'cause i'm always keep forgeting to free some resources / restore some state in "EXIT:" part. ;-) but i'm not saying that everyone should avoid gotos, and this is definitely the bug in compiler that should be fixed.
Aug 19 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
nrgyzer:

 Sure, I can also use nested functions, but in my opinion it 
 results in dirty and complex code. It's totally overkilled 
 compared to a simple if and goto-instruction.
Often nested functions are less complex, more clean and simpler code compared to using gotos. I suggest to start using nested functions and see how they work out. Bye, bearophile
Aug 19 2014
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/19/2014 01:04 AM, nrgyzer wrote:

 On Monday, 18 August 2014 at 17:47:21 UTC, ketmar via
 but why do you need gotos at the first place? i'm not saying that "you
 must avoid gotos at all costs!", but D has some nice features like
 scope(exit), scope(success), scope(failure) and nested functions, which
 can render gotos unnecessary in many cases (and make code cleaner).
I know, gotos are having a negative connotation. Sure, I can also use nested functions, but in my opinion it results in dirty and complex code. It's totally overkilled compared to a simple if and goto-instruction. The same regards the scoping... it's simply to much overhead.
However, goto is not a substitute for scope(exit) and friends or similar D features because goto may not be executed if an exception is thrown. Ali
Aug 19 2014
prev sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 18 August 2014 at 13:51:14 UTC, nrgyzer wrote:
 Hi all,

 I've the following code snipped:

 import std.bigint;
 void main(string[] args)
 {
 	BigInt i = "12345";
 	if (args.length > 1)
 	{
 		goto Exit;
 	}
 	i = BigInt("67890");
 	Exit:
 		return;
 }
For what it's worth, whenever you have "goto-end" style code, place all your code in a proper block, in such a way that all your variable declarations are in that block, and all your gotos break out of this block. This way, a goto will *never* cross a declaration, so coding is easy. The only variables you place at the top or the ones that could need cleanup. void main(string[] args) { //Declarations that need cleanup: void* p; //Code { BigInt i = "12345"; //Local variable if (args.length > 1) { goto Exit; //Breaks out of block } i = BigInt("67890"); BigInt j = "54321"; //Local variable } //End Exit: CleanUp(p); return; }
Aug 19 2014
parent reply "nrgyzer" <nrgyzer gmail.com> writes:
On Tuesday, 19 August 2014 at 20:33:00 UTC, monarch_dodra wrote:
 On Monday, 18 August 2014 at 13:51:14 UTC, nrgyzer wrote:
 Hi all,

 I've the following code snipped:

 import std.bigint;
 void main(string[] args)
 {
 	BigInt i = "12345";
 	if (args.length > 1)
 	{
 		goto Exit;
 	}
 	i = BigInt("67890");
 	Exit:
 		return;
 }
For what it's worth, whenever you have "goto-end" style code, place all your code in a proper block, in such a way that all your variable declarations are in that block, and all your gotos break out of this block. This way, a goto will *never* cross a declaration, so coding is easy. The only variables you place at the top or the ones that could need cleanup. void main(string[] args) { //Declarations that need cleanup: void* p; //Code { BigInt i = "12345"; //Local variable if (args.length > 1) { goto Exit; //Breaks out of block } i = BigInt("67890"); BigInt j = "54321"; //Local variable } //End Exit: CleanUp(p); return; }
Yes, that works. I'm using the goto-command to exit my function if an error (not necessarily an exception) occured. Sure, I can simply do a return, but I personally prefer a fixed endpoint of my functions. This also simplifies debugging my application because I don't need 10 or 20 breakpoints (one before each return-point).
Aug 21 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/21/2014 04:12 AM, nrgyzer wrote:

 I'm using the goto-command to exit my function
 if an error (not necessarily an exception) occured.
Sorry to repeat myself but if an exception occurs in code before the goto, the exit code will not be executed. Of course, it may be that the function is defined 'nothrow' so my concern does not apply.
 Sure, I can
 simply do a return, but I personally prefer a fixed endpoint of
 my functions.
Again, that is not possible in a language that has exceptions. Ali
Aug 21 2014
parent "nrgyzer" <nrgyzer gmail.com> writes:
On Thursday, 21 August 2014 at 17:39:16 UTC, Ali Çehreli wrote:
 On 08/21/2014 04:12 AM, nrgyzer wrote:

 I'm using the goto-command to exit my function
 if an error (not necessarily an exception) occured.
Sorry to repeat myself but if an exception occurs in code before the goto, the exit code will not be executed. Of course, it may be that the function is defined 'nothrow' so my concern does not apply.
 Sure, I can
 simply do a return, but I personally prefer a fixed endpoint
of
 my functions.
Again, that is not possible in a language that has exceptions. Ali
Sure, but what about the following pretty simple source: bool testa(int a) { bool fIsValid = (a > 0); if (a > 0) goto Exit; throw new Exception("int <= 0"); Exit: return fIsValid; } int main(string[] args) { testa(10); // Use goto testa(-1); // Throws an exception } I'm absolutely aware that gotos are useless if an exception occured before the goto appears. But in some cases they are very useful, especially when I want prevent 10 ident-steps or something else... Okay, my question was answered -> compiler bug. Thanks in advance!
Aug 21 2014