November 28, 2003
> > BTW, what about user defined enum? Can the compiler know whether all
enum
> > constants are used inside a switch, and signal to the programmer when
some
> are
> > missing and there is not a default?
>
> Yes, but it would be presumptious for the compiler to assume that all
values
> of an enum are possible.

Only if the default is there. Without the default, it would be appropriate.

But wait! This is another reason to have the default ...


November 28, 2003
> >>The only other way of doing this with a hope of robustness is to
> >> *require* an explicitly written default statement for every switch.
This
> >> would certainly be a valid language strategy, but I don't really want
to
> >be
> >> nagged by the compiler to insert a default:assert(0); when I know darn
> >well
> >> that x can never be 4 <g>.
> >
> >It's smacking me between the eyes that requiring the default is the
sensible
> >strategy. Original authoring costs are cheap; maintenance costs are expensive. You're just contradicting the bulk of this erudite argument by your knowingly weak convenience.
>
> I also support requiring default. The laziness is your biggest enemy,
> so type those 8 keys on the keyboard and that's all. But I know I'm almost
alone
> here: people want to save typing, not to produce robust code.

Well said.

Alas, what you say seems to be true a lot of the time. Even with big W ... :(


November 28, 2003
"Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:bq7boo$1g93$1@digitaldaemon.com...
> It is conceivable that due to a HW glitch or Act of God that x actually turns up 0 once every 4 billion runs.

I think that protecting against CPU hardware failures is beyond the scope of the language.

> If you can't be 200% sure, I would
> rather the compiler bitch at me, or automatically insert some code that
will
> never run, bloating my app by a few bytes, than take the chance of having execution fall off the end of my function.

It does the latter now <g>.

> It *is* possible to do this 100% if you require that all return paths are explicitly marked and handled, i.e. reject the above code as erroneous due to potential execution path problems.

Several C++ compilers do emit warnings for such. I find those warnings to be irritating rather than useful. For example, they will warn about:

    int foo()
    {
        while (1)
        {
                ....
                    return ...;
        }
    }

where it is *not possible* for the code to fall off the end, but the warning happens, and to get rid of it I have to put in a return statement that will never execute. I find being forced to add code that will never execute to be inelegant and potentially confusing. Hence my motivation for having D ensure that it never executes by raising an exception if it does, but that doesn't muck up the source code.



November 28, 2003
"Matthew Wilson" <matthew.hat@stlsoft.dot.org> wrote in message news:bq82ts$2jce$1@digitaldaemon.com...
> > I also support requiring default. The laziness is your biggest enemy, so type those 8 keys on the keyboard and that's all. But I know I'm
almost
> alone
> > here: people want to save typing, not to produce robust code.
>
> Well said.
>
> Alas, what you say seems to be true a lot of the time. Even with big W ... :(

Why is providing a runtime check that all the bases were covered make a program less robust? What really is the essential difference between requiring that the programmer explicitly code a default, and requiring him to explicitly check array bounds:

    if (0 <= i && i < array.length) j = array[i];

?


November 28, 2003
"Walter" <walter@digitalmars.com> wrote in message news:bq897h$2s6v$1@digitaldaemon.com...
>
> "Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:bq7boo$1g93$1@digitaldaemon.com...
> > It is conceivable that due to a HW glitch or Act of God that x actually turns up 0 once every 4 billion runs.
>
> I think that protecting against CPU hardware failures is beyond the scope
of
> the language.
>
> > If you can't be 200% sure, I would
> > rather the compiler bitch at me, or automatically insert some code that
> will
> > never run, bloating my app by a few bytes, than take the chance of
having
> > execution fall off the end of my function.
>
> It does the latter now <g>.
>
> > It *is* possible to do this 100% if you require that all return paths
are
> > explicitly marked and handled, i.e. reject the above code as erroneous
due
> > to potential execution path problems.
>
> Several C++ compilers do emit warnings for such. I find those warnings to
be
> irritating rather than useful. For example, they will warn about:
>
>     int foo()
>     {
>         while (1)
>         {
>                 ....
>                     return ...;
>         }
>     }
>
> where it is *not possible* for the code to fall off the end, but the
warning
> happens, and to get rid of it I have to put in a return statement that
will
> never execute. I find being forced to add code that will never execute to
be
> inelegant and potentially confusing. Hence my motivation for having D
ensure
> that it never executes by raising an exception if it does, but that
doesn't
> muck up the source code.

So your argument is that because some code analysers in some compilers are less than perfect, you'll change the language itself, and push out error detection from fool-proof and efficient compile-time to unexpected, surprising and inefficient runtime.

I am running out of adjectives on this one. Suffice to say, this is going to be really good ammunition for D-etractors.



November 28, 2003
"Walter" <walter@digitalmars.com> wrote in message news:bq8adb$2u45$2@digitaldaemon.com...
>
> "Matthew Wilson" <matthew.hat@stlsoft.dot.org> wrote in message news:bq82ts$2jce$1@digitaldaemon.com...
> > > I also support requiring default. The laziness is your biggest enemy, so type those 8 keys on the keyboard and that's all. But I know I'm
> almost
> > alone
> > > here: people want to save typing, not to produce robust code.
> >
> > Well said.
> >
> > Alas, what you say seems to be true a lot of the time. Even with big W
...
> > :(
>
> Why is providing a runtime check that all the bases were covered make a program less robust?

Anything that pushes out error-detection from (where it is achievable, of course) compile-time to runtime loses robustness. Isn't that axiomatic?

If that's not the case, then why don't we all program in Python all the time? It'd be a damn sight easier.

> What really is the essential difference between
> requiring that the programmer explicitly code a default, and requiring him
> to explicitly check array bounds:
>
>     if (0 <= i && i < array.length) j = array[i];
>
> ?

This is not a valid analogy. Your example is the difference between checking values yourself, or having them checked at runtime. With the switch/default, it is the case of having the options checked at compile time (by requiring all members of an enum to be present), or explicitly telling the compiler that you are aware of/don't care about the default case (with missing enums, or with other types) vs not being "complete" in the code and letting the runtime handle it. They are quite different things.



November 28, 2003
Does anyone disagree that C/C++'s switch semantics are dangerous, even if the (we) old farts have gotten used to it and rarely get bitten?

Does anyone think that it should be fixed in a way where implicit dangers still lurk for the unwary, whether that be inability to grok the new dangers, or the inability to get out of the mindset of the old (C/C++) semantics?

Isn't the only sensible approach to have the compiler enforce the semantics, and not allow any possibility of mistakes on our part?

Given that, why don't we simply accept the reality and have something along the lines:

1. Each case must end in break, throw, return, fallthrough or goto 2. The default case must be included.

At first blush it seems nice to allow default to be skipped when switching on an enum if all enum values are given cases. However, since they might be updated in one bit of client code after the creation of the object code containing the switch, this is probably not wise. Maybe this is where Walter's exception would get thrown. But I think this stinks (and I'm not alone), so I'd rather see either the default be required and the code explicitly request that the exception be throw, or we could have another case keyword unexpected


// 1, using default

int i

switch(i)
{
    case    1:
        func1();
        break;
    case    2:
        fallthrough: // I guess all you vowelly-challenged
western-hemisperians would probably go for fallthru here ... ;)
    case    3:
        func2_3();
        return;
    case    4:
        throw Some4Exception();
    case    5:
        goto label 5;
    default:
        break; // A null default
}


// 2, using unexpected

enum V
{
    a, b, c, d
}

V    v;

switch(v)
{
    case    a:
        func1();
        break;
    case    b:
        fallthrough: // I guess all you vowelly-challenged
western-hemisperians would probably go for fallthru here ... ;)
    case    c:
        func2_3();
        return;
    case    d:
        throw Some4Exception();
    unexpected:    // This doesn't have any contents (and it's an error to
have them), since it throws the exception that's currently thrown
}

Doesn't that cover every requirement that's been enunciated in this thread, whilst preventing any implicit behaviour whatsoever. The cost to these huge (IMO) benefits is that one must write default, or unexpected. Ouch! That's really going to slow down development times!




"Ian Woollard" <Ian_member@pathlink.com> wrote in message news:bk5nri$14cm$1@digitaldaemon.com...
> Just had a quick look at the switch statement.
>
> I noticed the syntax is:
>
> switch (foobar)
> {
> case 0:
> dostuff();
> // I've forgotten to break; all is lost.
> case 1:
> domorestuffIdidntreallywantto();
> break;
> default:
> }
>
> This isn't such a good idea. The default behaviour is really unsafe. I
would
> suggest a 'nobreak' statement for cases where you really do want the code
to
> fall through; otherwise  the compiler probably should fail to compile
(possibly
> switcheable off with a compiler option.)
>
> e.g.
>
> switch (foobar)
> {
> case 0:
> dostuff();
> nobreak; // we fall through, but that's fine.
> case 1:
> case 2: // note no nobreak required (although I wouldn't cry if it was)
> domorestuff();
> break;
> default:
> }
>
> Anyway, just an idea; probably a very good one IMNHO though.
>
> You might also consider the same idea in empty if and for statements.
>
> -Ian


November 29, 2003
"Matthew Wilson" <matthew.hat@stlsoft.dot.org> wrote in message news:bq8dbs$it$1@digitaldaemon.com...
> , or we could have another
> case keyword unexpected

I like!

Lars Ivar Igesund


November 29, 2003
Matthew Wilson wrote:

> I am running out of adjectives on this one. Suffice to say, this is going to
> be really good ammunition for D-etractors.

D-ctatorship rules. :>

Walter may be right, but when using Delphi i found that adding a line to shut up the code analyzer is not necessarily a bad idea. It expresses explicitly what would have happened anyway, so it improves the readability, not worsens it.

Especially it fits well with assertions being a language feature in D.

E.g. if one knows that a conditional on which execution path depends is necessarily zero, then one could either eliminate checks, or add an assert(var==0), which should be treated by a code analyzer as if variable was just assigned zero!

-eye

November 29, 2003
Roberto Mariottini wrote:
> I also support requiring default. The laziness is your biggest enemy,
> so type those 8 keys on the keyboard and that's all. But I know I'm almost alone
> here: people want to save typing, not to produce robust code.

Requiring default will bring us to people typing "default: break;" instead of "default: assert(0)"  just exactly for the reason you stated!

> BTW, what about user defined enum? Can the compiler know whether all enum
> constants are used inside a switch, and signal to the programmer when some are
> missing and there is not a default?

Cool idea!

-eye