C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Strongly-typed typedefs and enums
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Robert Kawulak
Guest





PostPosted: Thu Jul 01, 2004 11:45 pm    Post subject: Strongly-typed typedefs and enums Reply with quote



Classes are C++'s mechanism for creating 'strong' types, but their
definitions sometimes cause excess of form and make programmer write many
lines of code just to provide the same functionality as an already-defined
type, but forbid implicit conversions to/from this type. Typedefs, on the
other hand, let you define a new type basing on an existing one, but in fact
it's only a new name for the type. Consider following example: you need a
type for seconds in your program, so you use a typedef:

typedef unsigned TSeconds;

void ShowClock(TSeconds Time); //some funtion taking TSeconds argument

//later in the code...

TSeconds s;

ShowClock(s);

This approach isn't type-safe. If you have a function completely unrelated
to time measurement, say, a function computing miles when given kilometers:

unsigned KilometersToMiles(unsigned km);

then nothing stands in the way to call this function like this (which is not
uncommon programming error):

KilometersToMiles(s);

although it doesn't make any sense. The problem is the compiler considers
TSeconds and unsigned as the same type. Introduction of strongly-typed
typedef could be an elegant solution to this
problem. This could be done by reusing keyword 'new':

typedef new unsigned TSeconds;

or maybe

new typedef unsigned TSeconds;

Here, 'new' indicates (just like in Ada) that TSeconds is new, distinct
type, not yet another name for unsigned. Now the following call would result
in a compiler error, because implicit conversion cannot be done:

KilometersToMiles(s); //error: no function KilometersToMiles(TSeconds)

KilometersToMiles(static_cast<unsigned>(s)); //now OK, explicit
conversion

(Note: another, but very similar solution has been presented in suggestion
ES072, paper n1598).

There is a paper n1579 - "Strongly Typed Enums", dealing with a related
problem. However, proposed solution using 'enum class' seems a little bit
confusing to me (enums haven't much to do with classes making me think of
methods, fields and so on). For this reason, and for consequence (making
strongly-typed typedefs and enums being declared in the same way),
strongly-typed enums should, in my opinion, be created using 'enum new' (or
'new enum') rather than 'enum class'.

BTW, why wchar_t can't be an underlying type for a strongly-typed enum?

Greetings,
RK



---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Pete Becker
Guest





PostPosted: Fri Jul 02, 2004 11:13 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote



Robert Kawulak wrote:
Quote:

Introduction of strongly-typed
typedef could be an elegant solution to this
problem. This could be done by reusing keyword 'new':

typedef new unsigned TSeconds;

or maybe

new typedef unsigned TSeconds;

Here, 'new' indicates (just like in Ada) that TSeconds is new, distinct
type, not yet another name for unsigned. Now the following call would result
in a compiler error, because implicit conversion cannot be done:

KilometersToMiles(s); //error: no function KilometersToMiles(TSeconds)


As would all of the following:

TSeconds seconds = 3; // TSeconds seconds = static_cast<TSeconds>(3);
seconds++; // seconds =
static_cast<TSeconds>(static_cast<unsigned>(seconds) + 1);
ShowClock(seconds + 1); //
ShowClock(static_cast<TSeconds>(static_cast<unsigned>(seconds) + 1));

The adjective "elegant" doesn't accurately capture this.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Thomas Wicklund
Guest





PostPosted: Sat Jul 03, 2004 12:08 am    Post subject: Re: Strongly-typed typedefs and enums Reply with quote



Robert Kawulak wrote:

Quote:
typedef new unsigned TSeconds;
...

Here, 'new' indicates (just like in Ada) that TSeconds is new, distinct
type, not yet another name for unsigned. Now the following call would result
in a compiler error, because implicit conversion cannot be done:

KilometersToMiles(s); //error: no function KilometersToMiles(TSeconds)

KilometersToMiles(static_cast<unsigned>(s)); //now OK, explicit
conversion

Strong typing has a place, but unfortunately traditional strong typing
isn't as useful as one would like. Extending the above example (using
the syntax proposed):

typedef new double TTime;
typedef new double TDistance;
typedef new double TVelocity;

Now compute "velocity = distance / time". My experience is that code
like this is the reason that strong typing ala Pascal or Ada hasn't
caught on. I use PC-lint's strong typing, which provides a similar
capability to your proposal, and find I've got to populate the code with
casts or lint directives to get rid of mismatched type messages.

Personally I like the idea of being able to define types in terms of
units of measure and have the compiler enforce physics style unit
consistency. I've prototyped this using template classes and it can
probably be done with existing C++ (I've done a proof of concept,
haven't handled all the exception / conversion / etc. issues bound to be
lurking underneath). Most people don't agree with units of meaure as
the basis for a type system, and I have found that most proposals bog
down on issues of unit conversions (e.g. auto convert km to miles?) and
an explosion of types or constants.

That said, I would like to see a "strong" type, especially for enums,
which are much more likely to stay within the type. Strong types based
on numeric types have a place but, as my example above shows, they often
don't map into underlying concepts well.

Thomas Wicklund

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
edA-qa mort-ora-y
Guest





PostPosted: Sat Jul 03, 2004 1:22 am    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

Robert Kawulak wrote:
Quote:
problem. This could be done by reusing keyword 'new':
typedef new unsigned TSeconds;
or maybe
new typedef unsigned TSeconds;

I agree with the proposal, however I would suggest not using the word
'new' as it always implies an allocation/construction and although this
may not cause syntactic ambiguity, it causes needless confusion.

However, as what you really want is something that turns off implicit
type conversion, the explicit keyword could be reused in this sense (as
a shorthand to say each constructor is explicit and copy operators must
be explicit):

explicit typedef unsigned TSeconds;

With the default then also being specifically allowed:

implicit typedef unsigned TNumber;

--
edA-qa mort-ora-y (Producer)
Trostlos Records <http://trostlos.org/>

"What suffering would man know if not for his own?"

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Ivan Godard
Guest





PostPosted: Sat Jul 03, 2004 1:27 am    Post subject: Re: Strongly-typed typedefs and enums Reply with quote


"Thomas Wicklund" <wicklund (AT) eskimo (DOT) com> wrote

Quote:
Robert Kawulak wrote:

typedef new unsigned TSeconds;
...

Here, 'new' indicates (just like in Ada) that TSeconds is new, distinct
type, not yet another name for unsigned. Now the following call would
result
in a compiler error, because implicit conversion cannot be done:

KilometersToMiles(s); //error: no function
KilometersToMiles(TSeconds)

KilometersToMiles(static_cast<unsigned>(s)); //now OK, explicit
conversion

Strong typing has a place, but unfortunately traditional strong typing
isn't as useful as one would like. Extending the above example (using
the syntax proposed):

typedef new double TTime;
typedef new double TDistance;
typedef new double TVelocity;

Now compute "velocity = distance / time". My experience is that code
like this is the reason that strong typing ala Pascal or Ada hasn't
caught on. I use PC-lint's strong typing, which provides a similar
capability to your proposal, and find I've got to populate the code with
casts or lint directives to get rid of mismatched type messages.
...snip...
That said, I would like to see a "strong" type, especially for enums,
which are much more likely to stay within the type. Strong types based
on numeric types have a place but, as my example above shows, they often
don't map into underlying concepts well.

I solved the units problem in Mary2 by recognizing that there were three
distinct aspects to type for numeric quantities: representation, units, and
scale/bias. Languages like C++ either confound or ignore these. Extensions
(including libraries) have successfully handled a wider notion (for example,
a fixed-point integer package supporting representation and scale), but seem
cumbersome to use in practice. However (Mary2):

// from standard library
unit distance, time;
type meter = distance;
type centimeter = meter*100;
type second = time;
// in the app
type velocity = centimeters/second;
integer[4] velocity [1000 to 3000 by 5] v = 1500 centimeters/second;

seems pretty straightforward once you realize that the type constructors
read left-to-right rather than inside-out as in C; Mary was an Algol68
derivative. The last line says that variable "v" is declared to use integer
semantics and occupy four bytes, with a value representing every fifth
integer (scale by 0.2) from 1000 to 3000 and units of centimeters/second.
The representation is sparse because there are only 400 values and "v"
doesn't need integer[4] representation, but presumably the programmer had
his reasons Smile Now:

integer[4]meters/second v1 = v;

defaults the bias/scale for "v1", so the inialization with "v" will give
"v1" one of the 20 values (after rounding) that are common to both types.

In practice, there were two annoyances about full unit typing in Mary2. The
first was recurrences, where natural unit propagation leads to infinite
types; think Newton/Rapheson square root. You have to cast away the units
and reimpose them after the loop. In principle reflection directly into the
type system would avoid this (e.g. you could do it in SmallTalk), but Mary
didn't have that strong reflection facilities - it was done in the late 70s.
The second problem was generic libraries which would take in arguments in
arbitrary units and produce results in (usually different) arbitrary units.
Again, the function type should be able to algorithmetically specify the
result type as a function of the input types, which worked for simple
transformations (e.g. scaling) but not for all (e.g. integration).

In a strongly reflexive language all these problems could be handled, and
then you'd only be left with the residual human problem of all units-typing
schemes: the users don't want to be bothered :-)

Ivan

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Larry Evans
Guest





PostPosted: Sat Jul 03, 2004 3:06 am    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

On 07/02/2004 07:08 PM, Thomas Wicklund wrote:
[snip]
Quote:
Personally I like the idea of being able to define types in terms of
units of measure and have the compiler enforce physics style unit
consistency. I've prototyped this using template classes and it can
probably be done with existing C++ (I've done a proof of concept,
haven't handled all the exception / conversion / etc. issues bound to be
lurking underneath). Most people don't agree with units of meaure as
the basis for a type system, and I have found that most proposals bog
down on issues of unit conversions (e.g. auto convert km to miles?) and
an explosion of types or constants.

This has been discussed in the boost mailing list, e.g.

http://aspn.activestate.com/ASPN/Mail/Message/boost/1552662

http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?DimensionsAndUnits

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
James Kuyper
Guest





PostPosted: Sun Jul 04, 2004 7:23 am    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

[email]igodardA (AT) TpacbellDO (DOT) Tnet[/email] ("Ivan Godard") wrote in message news:<0SnFc.7795$7o4.6799 (AT) newssvr27 (DOT) news.prodigy.com>...
Quote:
"Thomas Wicklund" <wicklund (AT) eskimo (DOT) com> wrote in message
news:7LudnVE0aZeBfHjdRVn-sA (AT) csd (DOT) net...
...
In practice, there were two annoyances about full unit typing in Mary2. The
first was recurrences, where natural unit propagation leads to infinite
types; think Newton/Rapheson square root. You have to cast away the units
and reimpose them after the loop. In principle reflection directly into the

A better solution is to rearrange the calculations to make sure that
you multiply by a unitless factor at each step. Most correct infinite
recursions can be so rewritten. The result is often a better
algorithm, too, because it usually reduces the likelihood of over- and
under-flow.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Robert Kawulak
Guest





PostPosted: Sun Jul 04, 2004 6:01 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

Quote:
This could be done by reusing keyword 'new':
typedef new unsigned TSeconds;
or maybe
new typedef unsigned TSeconds;

I agree with the proposal, however I would suggest not using the word
'new' as it always implies an allocation/construction and although this
may not cause syntactic ambiguity, it causes needless confusion.

However, as what you really want is something that turns off implicit
type conversion, the explicit keyword could be reused in this sense (as
a shorthand to say each constructor is explicit and copy operators must
be explicit):

explicit typedef unsigned TSeconds;


You're right, I like your idea.

Quote:
With the default then also being specifically allowed:

implicit typedef unsigned TNumber;


Is there really such a need to introduce new keyword only for this purpose?

Greetings,
RK



---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Robert Kawulak
Guest





PostPosted: Mon Jul 05, 2004 4:16 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

Quote:
Now the following call would result
in a compiler error, because implicit conversion cannot be done:

KilometersToMiles(s); //error: no function
KilometersToMiles(TSeconds)


As would all of the following:


TSeconds seconds = 3; // TSeconds seconds = static_cast<TSeconds>(3);

That's right, similarly to

TSeconds seconds;
seconds = 3; //seconds = static_cast<TSeconds>(3);

and I consider this rather as advantage than disadvantage. I know the cast
is 'ugly' for you need to redundantly repeat 'seconds' type (that is
'TSeconds'). This problem, however, will be solved by introducing typeof
operator not forcing you to do this yet still making explicit cast possible:

seconds = static_cast<typeof(seconds)>(3);

or maybe

seconds = auto 3;
//Means: convert 3 to the type of seconds.
//Is it a good idea? Anybody?

Quote:
seconds++; // seconds =
static_cast<TSeconds>(static_cast<unsigned>(seconds) + 1);

Nop. TSeconds HAS ++ operator just like unsigned does, because it IS
unsigned except for it cannot be implicitly casted to this type (and any
other).

Quote:
ShowClock(seconds + 1); //
ShowClock(static_cast<TSeconds>(static_cast<unsigned>(seconds) + 1));

Same as above:

ShowClock(seconds + static_cast<typeof(seconds)>(1));

Greetings,
RK



---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
edA-qa mort-ora-y
Guest





PostPosted: Mon Jul 05, 2004 4:16 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

Robert Kawulak wrote:
Quote:
explicit typedef unsigned TSeconds;
You're right, I like your idea.
implicit typedef unsigned TNumber;
Is there really such a need to introduce new keyword only for this purpose?

No, there is no need, but I like completeness. :)


--
edA-qa mort-ora-y (Producer)
Trostlos Records <http://trostlos.org/>

"What suffering would man know if not for his own?"

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
kwikius
Guest





PostPosted: Mon Jul 05, 2004 4:18 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

[email]cppljevans (AT) cox-internet (DOT) com[/email] (Larry Evans) wrote in message news:<10ec1iq11rdg09f (AT) corp (DOT) supernews.com>...
Quote:
On 07/02/2004 07:08 PM, Thomas Wicklund wrote:
[snip]
Personally I like the idea of being able to define types in terms of
units of measure and have the compiler enforce physics style unit
consistency. I've prototyped this using template classes and it can
probably be done with existing C++ (I've done a proof of concept,
haven't handled all the exception / conversion / etc. issues bound to be
lurking underneath). Most people don't agree with units of meaure as
the basis for a type system, and I have found that most proposals bog
down on issues of unit conversions (e.g. auto convert km to miles?) and
an explosion of types or constants.

This has been discussed in the boost mailing list, e.g.

http://aspn.activestate.com/ASPN/Mail/Message/boost/1552662

http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?DimensionsAndUnits


You could also have a look here:

http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html

regards
Andy Little

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Pete Becker
Guest





PostPosted: Mon Jul 05, 2004 5:26 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

Robert Kawulak wrote:
Quote:

Nop. TSeconds HAS ++ operator just like unsigned does, because it IS
unsigned except for it cannot be implicitly casted to this type (and any
other).

Yup, and that's the problem. The definition of ++ for any builtin type
other than int (and bool, but that's a separate problem) requires
conversions. 5.3.2:

Quote:
The operand of prefix ++ is modified by adding 1 ...

If you can't add 1 you can't apply prefix ++. (In fact, that's why its
application to bool has to be described separately). The same problem
occurs with postfix ++.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Robert Kawulak
Guest





PostPosted: Tue Jul 06, 2004 6:24 am    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

Quote:
Nop. TSeconds HAS ++ operator just like unsigned does, because it IS
unsigned except for it cannot be implicitly casted to this type (and any
other).

Yup, and that's the problem. The definition of ++ for any builtin type
other than int (and bool, but that's a separate problem) requires
conversions. 5.3.2:

The operand of prefix ++ is modified by adding 1 ...

Now I see, you've got me here Wink So this would be one of challenges if
strong-typing is introduced to C++.



---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
John Nagle
Guest





PostPosted: Tue Jul 06, 2004 5:58 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

Robert Kawulak wrote:
Quote:
Consider following example: you need a
type for seconds in your program, so you use a typedef:

typedef unsigned TSeconds;

This is an old, old issue, and goes all the way back to Pascal.

The basic problem is that typing is lexical, not arithmetic.
It's not meaningful to add "meters" and "seconds", but it is
meaningful to divide meters by seconds. A strong typing scheme
that doesn't comprehend unit arithmetic will be more trouble than it
is worth.

John Nagle
Animats

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Hyman Rosen
Guest





PostPosted: Tue Jul 06, 2004 6:36 pm    Post subject: Re: Strongly-typed typedefs and enums Reply with quote

John Nagle wrote:
Quote:
A strong typing scheme that doesn't comprehend unit arithmetic
will be more trouble than it is worth.

Fortunately such a scheme is easy to write in Standard C++.
See Barton & Nackman, _Scientific and Engineering C++_.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.