Jump to page: 1 2
Thread overview
September 16

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."

September 16

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.

September 18
The compiler errs on the side of conservatism with this. It's worth filing a bug report for, but would be a low priority.
September 18
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!)
September 18
https://x.com/WalterBright/status/1968830567191036334
September 19

On Friday, 19 September 2025 at 00:02:53 UTC, Walter Bright wrote:

>

gcc does not produce an error:

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!)

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:

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

September 19

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.

September 22
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.

September 22
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.
September 23
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
« First   ‹ Prev
1 2