www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - goto skipping declarations

reply claptrap <clap trap.com> writes:
void foo(bool x)
{
         goto END;
         uint what;
     END:
}

 onlineapp.d(15): Error: `goto` skips declaration of variable 
 `onlineapp.foo.what`
        goto END;
        ^
void foo(bool x) { { goto END; uint what; } END: } runs fine. I think it's correct behaviour, if the goto is jumping out of its scope, its OK to skip declarations in that scope, since they cant be accessed outside it. But the documentation doesn't specify this behaviour. It just says... "It is illegal for a GotoStatement to be used to skip initializations." it should say something like "It is illegal for a GotoStatement to be used to skip initializations within its containing scope."
Sep 15
next sibling parent Dennis <dkorpel gmail.com> writes:
On Tuesday, 16 September 2025 at 04:57:33 UTC, claptrap wrote:
 But the documentation doesn't specify this behaviour. It just 
 says...
Thanks for reporting, I've created an issue for it: https://github.com/dlang/dlang.org/issues/4310 If you find more spec improvements, please post them there as well.
Sep 16
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
The compiler errs on the side of conservatism with this. It's worth filing a
bug 
report for, but would be a low priority.
Sep 18
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
gcc does not produce an error:

```c
int foo(int x)
{
         goto END;
         int what;
     END: return what;
}
```

so D is still doing better! D gives an error. (ImportC does not give an error, 
on purpose!)
Sep 18
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Friday, 19 September 2025 at 00:02:53 UTC, Walter Bright wrote:
 gcc does not produce an error:

 ```c
 int foo(int x)
 {
         goto END;
         int what;
     END: return what;
 }
 ```

 so D is still doing better! D gives an error. (ImportC does not 
 give an error, on purpose!)
```c int foo(int x) { goto END; int what = 0; END: return what; } ``` Does yield an error: ``` <source>: In function 'int foo(int)': <source>:5:5: error: jump to label 'END' 5 | END: | ^~~ <source>:3:12: note: from here 3 | goto END; | ^~~ <source>:4:11: note: crosses initialization of 'int what' 4 | int what = 0; | ^~~~ Compiler returned: 1 ``` So the skipping of initialization is technically caught, it's just that D default initializes and C does not. Let's try D code that doesn't initialize: ```d int foo(int x) { goto END; int what = void; END: return what; } ``` Same error. I still like the D mechanism better, as it's very likely you didn't mean to do this, and it's generally better to avoid this problem. -Steve
Sep 18
next sibling parent reply Derek Fawcus <dfawcus+dlang employees.org> writes:
On Friday, 19 September 2025 at 02:03:57 UTC, Steven 
Schveighoffer wrote:
 On Friday, 19 September 2025 at 00:02:53 UTC, Walter Bright 
 wrote:
 gcc does not produce an error:
Yup, and has done for a while - one just needs to enable the errors (it is a bit sad that '-Wall' stopped having things added, so creating '-Wextra'): ``` $ gcc-11 -Wall -Wextra -Werror -c skip.c skip.c: In function ‘foo’: skip.c:1:13: error: unused parameter ‘x’ [-Werror=unused-parameter] 1 | int foo(int x) { | ~~~~^ skip.c:5:14: error: ‘what’ is used uninitialized [-Werror=uninitialized] 5 | return what; | ^~~~ cc1: all warnings being treated as errors ``` The complaint about 'what' happens with '-Wall' alone. If one used gcc-12 and later, it also states where 'what' is declared.
Sep 19
parent Walter Bright <newshound2 digitalmars.com> writes:
The unused parameter is not an actual error. It is not uncommon to not need to 
use all parameters in, say, an implementation of a lambda.

Returning uninitialized data, however, is an actual error. It should not be a 
warning, it should be part of the core language.
Sep 22
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/18/2025 7:03 PM, Steven Schveighoffer wrote:
 So the skipping of initialization is technically caught, it's just that D 
 default initializes and C does not.
In C, the function still returns an uninitialized value. Some people on X told me that throwing more compiler switches, and/or running various linters and code analyzers, would detect the problem. That's true, but the *language* as specified does not detect these problems.
Sep 22
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 23/09/2025 5:31 AM, Walter Bright wrote:
 On 9/18/2025 7:03 PM, Steven Schveighoffer wrote:
 So the skipping of initialization is technically caught, it's just 
 that D default initializes and C does not.
In C, the function still returns an uninitialized value. Some people on X told me that throwing more compiler switches, and/or running various linters and code analyzers, would detect the problem. That's true, but the *language* as specified does not detect these problems.
Indeed, this specific analysis is very common, and given the recent work to solve UB in C2Y, I'm surprised it hasn't come up yet. Although they at least have one example of this: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3453.pdf
Sep 22
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Monday, 22 September 2025 at 17:31:49 UTC, Walter Bright wrote:
 On 9/18/2025 7:03 PM, Steven Schveighoffer wrote:
 So the skipping of initialization is technically caught, it's 
 just that D default initializes and C does not.
In C, the function still returns an uninitialized value.
As I mentioned in a reply, so does D. -Steve
Sep 22
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
https://x.com/WalterBright/status/1968830567191036334
Sep 18