Is this a bug? +goto

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Nov 8 06:56:14 UTC 2018


On Wednesday, November 7, 2018 10:50:29 PM MST Michelle Long via 
Digitalmars-d-learn wrote:
> On Thursday, 8 November 2018 at 02:22:42 UTC, Jonathan M Davis
>
> wrote:
> > On Wednesday, November 7, 2018 1:03:47 PM MST Michelle Long via
> >
> > Digitalmars- d-learn wrote:
> >> Don't let their psychobabble fool you. They are wrong and you
> >> were right from the start.
> >
> > ...
> >
> >> Case A:
> >> {
> >>
> >>     if (true) goto X;
> >>     int x;
> >>
> >> }
> >> X:
> >>
> >>
> >> Case B:
> >> {
> >>
> >>     if (true) goto X;
> >>     {
> >>
> >>        int x;
> >>
> >>     }
> >>
> >> }
> >> X:
> >>
> >>
> >> These two cases are EXACTLY the same semantically. It's like
> >> writing A + B and (A + B).
> >
> > That's not the situation that the OP was describing. If adding
> > braces in a situation where the braces have no semantic effect
> > has any impact on goto, then it's a compiler bug. It's adding a
> > new scope that affects the lifetime of a variable whose
> > declaration is being jumped over by a goto that matters.
> >
> > I know that you're frustrated, because you've hit a problem
> > with goto in complex code, and you don't have a simple example
> > that shows the compiler bug, but the approach that D takes with
> > goto (and any construct that potentially requires code flow
> > analysis) of avoiding requiring that the compiler be smart is
> > precisely to reduce the risk of there being cases where the
> > compiler is going to screw it up in complex code even though it
> > gets it right in the simple cases. If the language required the
> > compiler to be smart about such things, we'd have a lot more
> > problems with subtle, hard to track down compiler bugs in
> > complex code. So, we'd just have _more_ cases where people
> > would be hitting frustrating bugs like you are.
>
> That's fine. The D compiler writers can decide to do whatever
> they want. I can simply take my "business" elsewhere if I don't
> like it.
>
> What I am talking about is about an obvious error(Ok, I haven't
> produced a simplified test case but dustmite or visual D is not
> working for me to do so at this point in time, but it would be
> nice for sake of argument to assume I'm right...).
>
> > Regardless, if you want to actually have your problem fixed,
> > you're going to need to provide a reproducible test case in a
> > bugzilla report, even if it's large, otherwise no one is going
> > to be able to track it down for you.
>
> That's easier said than done. I wasn't expecting anyone to be
> able to fix a bug that can't be reproduced.
>
> What I expect is that, given my assumptions that I'm right, that
> people can agree the compiler does have a bug or flaw that can
> easily be fixed give then two simplified test cases basic purely
> what I have done in my own code.
>
> 1.
>
> foreach(...)
> {
>    if (x) goto Y:
>    int z;
> }
> Y:
>
> Fails.
>
> foreach(...)
> {
>    if (x) goto Y:
>    {
>       int z;
>    }
> }
> Y:
>
> Passes.
>
> THAT IS FACT! It doesn't matter if the examples work above. I
> have simplified what I have done and in my code I simply add
> brackets and it works! That is what people should be thinking
> about... not test cases, MWE's, compiler versions, etc.
>
> Is it logical that the compiler **should** error out in the first
> case and no in the second?
>
> That is what the discussion is ALL about. Once that is dealt with
> then we can move on to finding out more specifics. There is no
> reason to build the windows of a house before the foundation,
> it's just far more work without any benefit.
>
>
> Once people can say: If that is all you are doing is adding
> brackets around what follows the goto and break out of
> scope(which is what the code above says) and you can compile,
> then it is a compiler bug or flaw.
>
> Once people verify that, rather than trying to create rabbit
> holes, then I can do more work on finding out more specifics.
> Until then, it is pointless to do anything on my side because if
> people come back and say "No, it is suppose to work that way"
> then what the hell am I trying to simplify and fix? It's not a
> bug then.

If you have code where you get a compiler error about a goto skipping the
initializiation of a variable, and you add braces that should have no
semantic effect on the code whatsoever, and the error goes away, then yes,
that's a compiler bug. If, however, the braces do affect the semantics of
the code, then that's not necessarily a compiler bug. At that point, whether
it's a compiler bug or not would depend on what exactly the code was.

In an example such as

while(1)
{
    if(cond)
        goto label;
    int x;
}
label:

adding braces such as

while(1)
{
    if(cond)
    {
        goto label;
    }
    int x;
}
label:

or

while(1)
{
    if(cond)
        goto label;
    {
        int x;
    }
}
label:

should have no effect. However, in an example such as

goto label;
int x;
label:

adding braces such as

goto label;
{
    int x;
}
label:

changes the code entirely. It puts the variable x in a new scope such that
it no longer exists at the label, and as such, its entire existence is
skipped.

Braces matter for gotos because of how they affect scopes. If they're placed
in a way that they don't affect scope, then they should have no effect on
gotos. If they do affect scopes, then they can affect gotos, but whether
they do or not is going to depend on the code. The key thing is that gotos
cannot skip over the initialization of variables such that at the label, a
variable now exists that did not exist at the goto. Variables can be skipped
which would have come into scope and then left scope, but any declarations
for variables which have not left scope are not allowed between the goto and
the label. Braces can obviously affect that, and so braces can matter a
great deal. But braces can also be used in ways that are optional, and if
the braces are optional, then they don't affect scope, and they should have
no effect on gotos.

> But what it seems is that people cannot reason about the purely
> theoretical underpinnings of the problem and need proof that
> there is even a problem in the first place, as if I'm making it
> up and then they create all kinds of obfuscation that doesn't
> help anyone.
>
> If you can agree that removing the brackets in the two test cases
> should work in ALL regular cases then I can attempt to provide
> more information.
>
> Again, until then, it is pointless. I could waste 10 hours trying
> to track the issue down to provide a test case and you can just
> come back and say "Oh, no, that is not a bug, it's suppose to be
> that way. We will not change anything". I know from previous
> history that is the typical mentality.
>
> Until We can agree that it is a bug, it is pointless for me to
> treat it as a bug.

Honestly, without seeing actual code that reproduces the problem, it's very
difficult for any of us to accurately tell you whether you're seeing a bug
or not. We can try to explain the language rules, and we can say whether we
think what we're seeing is a bug based on what you describe, but with how
easy it often is to misunderstand a problem when you have the actual code in
front of you to study, dealing with everything second hand is bound to be a
flawed process. I know that such situations can be very frustrating, but it
is going to be very difficult for us to give you a definitive answer.

I can tell you that if adding braces which should have zero semantic effect
on the code makes the error about skipping a variable's initialization with
goto go away, then it definitely sounds like you found a compiler bug. But
otherwise, I have no way of knowing without an actual piece of code that
exhibits the problem, and regardless, without an actual piece of code that
exhibits the problem, the compiler devs won't be able to fix anything.

> > Now, a goto-related regression has recently been reported for
> > joiner:
> >
> > https://issues.dlang.org/show_bug.cgi?id=19213
> >
> > where some code worked with joiner in 2.081.2 but does not work
> > with 2.082.0 or later, so you may want to test your code with
> > an older compiler release to see if you've hit a compiler
> > regression. If so, that could be a starting point for tracking
> > down the problem.
>
> Until I can simplify the code I have, it won't matter. If it is
> the same bug, then it will get fixed when it gets fixed with
> joiner. If it is a different bug, then it will get fixed with I
> can produce a test case.
>
> While I could prove that it is a version issue by trying a
> different compiler version(I guess I should keep an old one
> around for that purpose) it seems it is likely that it is the
> same bug...

Well, if an older version of the compiler works for you, it at least lets
you work around the problem for now even if it doesn't actually fix your
problem long term, and someone _has_ produced a reduced example for that bug
report, so if you have the same problem, it should be only a matter of time
before your problem is fixed. Also, if it turns out that an older compiler
version works for you, but it's a different problem, then it would be
possible (albeit a bit of work) to figure out which commit broke your code,
which would go long way to finding a fix. If an older compiler version
doesn't work for you, then it doesn't really help you, but at least you then
know that whatever problem you're hitting is not the same as that bug
report.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list