Failure of type safety system to catch error -- why?

Failure of type safety system to catch error -- why?

Post by Francis Glassboro » Fri, 01 Aug 2003 08:55:36





Quote:>Using a switch (or, equivalently, a series of if (blah == foo)
>statements) ties the meaning of the enumerator (i.e. what code path
>will be executed) directly to the name of the enumerator.  Easier to
>get right, harder to get wrong, IMHO.

And much harder to maintain. Actually I do use switch statements and
enums for multi-way choices but only where almost all the implementation
is tucked away in an unnamed namespace (including the enum which is only
used for inter-function communication).

--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow      ACCU

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by Steve Foll » Fri, 01 Aug 2003 08:57:34






>>> I've seen compilers issue warnings when the expression used
>>> in an if test is constant, at least in some forms.  It can
>>> be annoying if they do so for if(true) or if(false) as I find
>>> those occasionally preferable to conditional compilation
>>> though.

>> I don't mean "if" conditions which depend on constants. The code here was

>>         enum Something { /* ... */} ;

>>         void f( Something foo )
>>         {
>>                 if( foo ) doBar();
>>         }

>> I.e. an "if" statement which takes a (non-constant) enum value. I don't
>> think this is idiomatic C++ in any way; however, Andy seems to disagree.

> As do I; it's fairly consistent with the traditional C and C++
> abuse of contexts where boolean expressions "ought" to be used
> (and without any implicit conversions going on).  So, I'd say
> that it's fairly idiomatic, although I'd prefer to work with
> coding conventions that ban such use.

The problem here (as far as I can tell), from the OP seems to resolve around
enums being implicitly converted to other types, particularly bools (and
ints?).

Would a simple language syntax enhancement not solve this? Just use
'explicit' before an enum declaration? Such enums would then be excluded
from implicit conversions. Eg:

enum priority { slave, master };
priority p = slave;
if( p ) // would compile, and would be false

[Q:does The Standard guarantee enums are assigned values starting from
zero?]

BUT

explicit enum priority { slave, master };
priority p = slave;
if( p ) // would not compile because priority cannot be implicitly converted

Just a thought.

I don't think this would break any existing code (which is still prone to
errors), but new code would enable more errors to be spotted at compile
time. 'explicit' is already a keyboard.

Of course, I realise this wont solve your immediate problems, and would
probably take a while (if ever) before it made its way into compilers of the
future.

--
Regards,
Steve.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by Pete Becke » Fri, 01 Aug 2003 21:45:04



> The problem here (as far as I can tell), from the OP seems to resolve around
> enums being implicitly converted to other types, particularly bools (and
> ints?).

> Would a simple language syntax enhancement not solve this? Just use
> 'explicit' before an enum declaration? Such enums would then be excluded
> from implicit conversions.

Nope. A programmer who doesn't know that enums can be converted to bools
won't know to use 'explicit' to prevent it. One who does know won't
write code that needs this hack. One of the fundamental rules of
language design is that you don't design for beginners. Nobody stays a
beginner for long, and they soon find that they don't like having to
work around all those "helpful" features.

--

"To delight in war is a merit in the soldier,
a dangerous quality in the captain, and a
positive crime in the statesman."
        George Santayana

"Bring them on."
        George W. Bush

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by James Dennet » Fri, 01 Aug 2003 21:47:53



 >
 >

[snip]

 >> > I.e. an "if" statement which takes a (non-constant) enum value. I don't
 >> > think this is idiomatic C++ in any way; however, Andy seems to disagree.
 >> >
 >>
 >>As do I; it's fairly consistent with the traditional C and C++
 >>abuse of contexts where boolean expressions "ought" to be used
 >>(and without any implicit conversions going on).  So, I'd say
 >>that it's fairly idiomatic, although I'd prefer to work with
 >>coding conventions that ban such use.
 >
 >
 > I used to think this, when I was in college. Since then I've found
 >     most programmers I've worked actually read:
 >
 >     while(cin >> foo)
 >     {
 >         /* something with foo*/
 >     }
 >
 >     more easily than:
 >
 >     while(cin >> foo != 0)
 >     {
 >         /* something with foo*/
 >     }

OK, I'll turn around and disagree with myself; in C++, with
its standard library, trying to fight against implicit conversions
is a road to madness.  The simple cast of while (cin >> foo),
which is idiomatically entirely clear and even has a certain
kind of elegance to it, involves a user-defined conversion to
void* and then is converted again to bool.

I'll take my "pure", "academic" ideas about implicit conversions
to and from bool elsewhere.  Well, maybe I'll still hang on to
my loathing of bool->int...

-- James.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by Francis Glassboro » Sat, 02 Aug 2003 02:57:22




Quote:>Would a simple language syntax enhancement not solve this? Just use
>'explicit' before an enum declaration? Such enums would then be excluded
>from implicit conversions. Eg:

>enum priority { slave, master };
>priority p = slave;
>if( p ) // would compile, and would be false

>[Q:does The Standard guarantee enums are assigned values starting from
>zero?]

Unless a value is specified for the first enumeration constant, yes.
Quote:

>BUT

>explicit enum priority { slave, master };
>priority p = slave;
>if( p ) // would not compile because priority cannot be implicitly converted

True but without an extensive rewrite of the standard most other uses of
explicit enums would also fail. For example their use for cases in
switch statements rely on the implicit conversion to int.

--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow      ACCU

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by ka.. » Sat, 02 Aug 2003 04:08:23






> >  >>I've seen compilers issue warnings when the expression used
> >  >>in an if test is constant, at least in some forms.  It can
> >  >>be annoying if they do so for if(true) or if(false) as I find
> >  >>those occasionally preferable to conditional compilation
> >  >>though.
> > > I don't mean "if" conditions which depend on constants. The code
> > >  here was
> >  >         enum Something { /* ... */} ;

> >  >         void f( Something foo )
> >  >         {
> >  >                 if( foo ) doBar();
> >  >         }
> >  > I.e. an "if" statement which takes a (non-constant) enum value. I
> >  > don't think this is idiomatic C++ in any way; however, Andy seems
> >  > to disagree.
> > As do I; it's fairly consistent with the traditional C and C++ abuse
> > of contexts where boolean expressions "ought" to be used (and
> > without any implicit conversions going on).  So, I'd say that it's
> > fairly idiomatic, although I'd prefer to work with coding
> > conventions that ban such use.
> I used to think this, when I was in college. Since then I've found
>     most programmers I've worked actually read:
>     while(cin >> foo)
>     {
>         /* something with foo*/
>     }
>     more easily than:
>     while(cin >> foo != 0)
>     {
>         /* something with foo*/
>     }

This is a special case -- "cin >> foo != 0" is misleading.  The possible
alternative would be more along the lines of:

    while ( ! (cin >> foo).fail() ) {
    }

which is excessively awkward, and leads programmers to want to invert
the logic and write:

    while ( (cin >> foo).good() ) {
    }

(which doesn't work).

The basic logic is that a stream is true if the last operation
succeeded, false otherwise.  The fact that this "bool" is actually
implemented with a pointer is irrelevant.  You don't want to compare it
to 0 any more than you would compare a bool variable to 0.

Quote:>     and chosing a function name to make 'if(some_condition())' and
>     such read nicely is easier than making 'if(some_condition() != 0)'
>     read nicely.
> Of course, the fact that these things are associated with implicit
>     conversions is largely a matter of history (and for a new
>     function, the 'some_condition()' from above should usually return
>     bool, but lots of functions named nicely for if and while return
>     int), but that's what we have.

Right.  What really matters is what the value is logically.  Thus, in
the case of iostream, you are converting to a pointer, but the only
thing guaranteed about the pointer is that it is either NULL or not; the
non-null pointer value has no significance other than that it is not
null.  It is, in fact, a pre-bool bool.  That doesn't invalidate the
rule that if a non-bool is involved, you should write out the
comparison.

--

Conseils en informatique oriente objet/     http://www.gabi-soft.fr
                    Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by Igor Ivan » Sat, 02 Aug 2003 17:46:25



 > >
 > > The problem here (as far as I can tell), from the OP seems to resolve around
 > > enums being implicitly converted to other types, particularly bools (and
 > > ints?).
 > >
 > > Would a simple language syntax enhancement not solve this? Just use
 > > 'explicit' before an enum declaration? Such enums would then be excluded
 > > from implicit conversions.
 >
 > Nope. A programmer who doesn't know that enums can be converted to bools
 > won't know to use 'explicit' to prevent it.

Fine.

 > One who does know won't write code that needs this.

I would like to see a good alternative within the existing language
rules, if there is one.

 > hack.

This is not a hack. This is a language enhancement suggestion. Pascal
has type safe enumerations and they proved to be very useful for
ensuring type safety.

 > One of the fundamental rules of
 > language design is that you don't design for beginners. Nobody stays a
 > beginner for long, and they soon find that they don't like having to
 > work around all those "helpful" features.

There's no need for workarounds. Programmers who don't make mistakes
would be able to use enums as before if they don't specify the
explicit keyword.

Igor

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by Pete Becke » Sun, 03 Aug 2003 18:06:58



> I would like to see a good alternative within the existing language
> rules, if there is one.

>  > hack.

> This is not a hack. This is a language enhancement suggestion. Pascal
> has type safe enumerations and they proved to be very useful for
> ensuring type safety.

In C++ it's a hack.

Quote:

>  > One of the fundamental rules of
>  > language design is that you don't design for beginners. Nobody stays a
>  > beginner for long, and they soon find that they don't like having to
>  > work around all those "helpful" features.

> There's no need for workarounds. Programmers who don't make mistakes
> would be able to use enums as before if they don't specify the
> explicit keyword.

Nope. Since you never know when some maintenance programmer might change
the semantics of an ordinary enum that you're using, if you want
conversions you'd have to make them explicit.

If you don't like the semantics of enums don't use them. Write a class
and make it do whatever you want it to do. That's what they're for.

--

"To delight in war is a merit in the soldier,
a dangerous quality in the captain, and a
positive crime in the statesman."
        George Santayana

"Bring them on."
        George W. Bush

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Failure of type safety system to catch error -- why?

Post by Igor Ivan » Mon, 04 Aug 2003 05:00:09



> > This is not a hack. This is a language enhancement suggestion. Pascal
> > has type safe enumerations and they proved to be very useful for
> > ensuring type safety.

> In C++ it's a hack.

I don't understand why you keep saying this. We are talking about a
supposed language extension. A hack is some illegal trick within the
existing language.

Quote:

> > There's no need for workarounds. Programmers who don't make mistakes
> > would be able to use enums as before if they don't specify the
> > explicit keyword.

> Nope. Since you never know when some maintenance programmer might change
> the semantics of an ordinary enum that you're using, if you want
> conversions you'd have to make them explicit.

This could be said about many existing features. What if that
programmer started to add explicit to previousy written ctors or
adding private: to structs?

Quote:

> If you don't like the semantics of enums don't use them. Write a class
> and make it do whatever you want it to do. That's what they're for.

I am not sure what you mean. Do you have in mind the semantics of type
safe enums expressed via classes? Hopefully such beasts would have
similar to enum syntax and easy to declare, define and use. If this a
well-known and established idiom in C++, could you please give me
relevant links. All I was able to find searching were some discussions
of what this or that poster used which were far from industrial
strength solutioms.

Igor

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]