Topic: enum size


Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/06/21
Raw View
jonathan@cae.ca (Jonathan Hutchinson) writes:

>Is it possible to create a public const variable that is set to a
>proivate non-const variable, thereby giving the user's of the class
>a readonly view of the variable, while members and friends have a
>modifiable version?

Sure, you can do it, but it is not efficient.

>I know the following code does not work, but is there a way to get
>the result it is attempting to achieve?
>
>class TestIt
>{
>    int modifiable; // internal non-const variable
>public:
>    int &const non_modifable = modifiable;  // external scope
>         // non modifiable version
>};

Write that as

 class TestIt
 {
  int modifiable;  // internal non-const variable
 public:
  const int & non_modifiable; // public const reference to
      // internal variable

  // initialize the reference in the constructor
  TestIt() : non_modifiable(modifiable) {}
 };

>BTW, the non_modifable variable is supposed to be a reference to an
>int that is const (not the int, but the reference) Does that make any
>sense.

No - references can never be modified to refer to something different
once they have been initialized.  So the `const' in
`int &const non_modifable' is redundant (and in fact illegal
according to the draft standard, although some old compilers may still
accept it).

>the const is supposed to ensure that the original int will not
>be modified by the reference version...

In that case, you should put the `const' on the int, not the reference,
as in my code above.

--
Fergus Henderson
fjh@cs.mu.oz.au
http://www.cs.mu.oz.au/~fjh





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/06/17
Raw View
maxtal@Physics.usyd.edu.au (John Max Skaller) writes:

> class X { int i;
> public:
>  int const &j;
>  int const &geti()const {
>   return const_cast<X*>(this)->i;
>  }
>  X() : j(i) {}
> }

Uh, why bother with the const_cast?
Just

  int const &geti() const { return i; }

should do - shouldn't it?

--
Fergus Henderson
fjh@cs.mu.oz.au
http://www.cs.mu.oz.au/~fjh





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/06/15
Raw View
In article <3rdg23$70@oncomdis.on.ca>, joshua <joshua@oncomdis.on.ca> wrote:
>Stephen Williams (steve@spokane.ia-us.com) wrote:
>: That compiler would be in error:
>
>: 6 For an enumeration where emin is the smallest enumerator and  emax  is
>:   the  largest,  the  values  of  the  enumeration are the values of the
>:   underlying type in the range bmin to bmax, where bmin  and  bmax  are,
>:   respectively,  the  smallest  and  largest values of the smallest bit-
>:   field that can store emin and emax.
>
>: All the intermediate numbers are valid enumeration values, even though
>: they do not have a name.
>
>Boy, that's a new one!  The ONLY valid values for an enum are in it's
>definition, otherwise why bother having enums as all?
>
>I'd like to know where you heard otherwise.

 Joshua -- the quotation above is straight
out of the Committe Draft of the C++ Standard.

 Your idea corresponds to the Pascal notion of enumeration
type -- not the C/C++ one.

--------------------------------------------------------------------------
This space is reserved for an advertisement.
I'm forced to include it by my stupid News server.
Sorry.
--------------------------------------------------------------------------

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/13
Raw View
In article <3r70mh$au2@nntpd.lkg.dec.com> porter@mu.enet.dec.com (dave
porter) writes:

|> In re:

|> : >The realy smart compiler will work out that for
|> : >enum { a, b, c. WorkArround=9999999 }
|> : >  that it only needs a char to implement this enum. It stores
|> : >  127 for the WorkAround value and when converting the enum to int  maps 127 to
|> : >  9999999 and when converting int to the enum maps 9999999 to 127.

|> : I don't think that is permitted.  From the draft spec, ......

|> bkline@cortex.nlm.nih.gov (Bob Kline Phoenix Contract) wrote:

|> > Nor is it desirable.  Too much existing code relies on enumeration
|> > values used as bitmasks.

|> But how could you tell?  I assume that any context which used
|> an enum value as a bitmask would actually convert the enum to
|> an int, thus undoing the "enum compression".

And you can (according to the standard) store the results in an enum
of the same type, thus:

 enum X { a = 0x01 , b = 0x02 , c = 0x04 } ;
 X               x = (X)( a | b | c ) ;

Thus, in the above example, it is necessary to be able to store (and
of course read) all values between 1 and 7.






--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/13
Raw View
In article <3r7pq1$jm5@oncomdis.on.ca> joshua@oncomdis.on.ca (joshua)
writes:

|> I'll give a clean answer to the questions in this thread:
|> (it got really muddy)

|> the only (portable) way to know the real size of an enum
|> is to use sizeof(enum_name)

|> you can't predict what the size of an enum will be from
|> the values in it's definition

But you can predict its minimum size.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: ti953017@rzcipa01.rz.tu-bs.de (Andreas Rossberg)
Date: 1995/06/09
Raw View
In article <D9JBKx.3xt@ukpsshp1.serigate.philips.nl>,
Stephen Baynes <baynes@ukpsshp1.serigate.philips.nl> wrote:
>
> In my view if the standard prohibits the use of ++ and -- on enums (which is
> what now seems to be the case) then that is a bad decision by the standard
> makers. It is often necessary to itterate over a enumerated type.


Note that iterating over enumerations is very dangerous. Consider

 enum E { first = 0, /* ... */ last = XXXX };

 // ...

 // consider e++ to be defined to mean s/th like e = E(e+1)
 for (E e = first; e <= last; e++) ...

This can always result in an infinite loop (imagine for example, XXXX
happens to be 255 and the compiler chooses to store an E in a single byte).

AFAIK, there is no safe way for simple iteration over the range of an enum.
The standard could fix this by requiring enum objects always to be able to
hold a last+1 (and first-1, to allow reverse iteration) value; similar to
the pointer past last array element concept.

I always define that last+1 element myself to ensure that iteration works:

 enum Color { red, green, blue, yellow, maxColor };

However, that's a little bit tedious and ugly (as maxColor isn't a color
and I have to invent names for each enumeration). But I think I can live
with it (luckily, I rarely need reverse iteration).

As a footnote: For those who think C++'s flexible notion of the for statement
is superior to that of other languages, here is a case it cannot handle. The
same problem arises when trying to iterate up/down to the maximum/minimum
value of an integral type - it just overflows. In Modula, for example, such
FOR statements are guaranteed to work, because FOR isn't just WHILE.


 - Andreas Rossberg





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/06/09
Raw View
In article <3r437l$egn@triode.apana.org.au>,
Ben Aveling <bena@triode.apana.org.au> wrote:
>John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
>: Ben Aveling <bena@triode.apana.org.au> wrote:
>
>: >My biggest complaint about C++ is that a class can't easily export
>: >read-only variables to the general public.
>
>:  Sure it can. Two ways at least:
>
>:  class X { int i;
>:  public:
>:   int const &j;
>
>That doesn't count - I still want it read/write inside my class.

 It IS. You didn't look at the next line:
>
>:   }
>:   X() : j(i) {}
>:  }

 So INSIDE the class you can modify i but outside the class,
you cannot access i (its private) but you can access j -- but only
for read. j refers to i.

 The main disadvantage of this technique is that usually
j will be implemented as a pointer -- take up space and slow
down dereferencing. It is error prone and requires
extra work by the programmer then compiler and the run-time system.

>OK, all of these things can be done by overloading operators, but
>let's put it this way;  Who here wouldn't like to be able to easily
>specify a variable's visibility with the sort of precision I've used
>in my example?

 A "subset" of what you are asking for -- read only
access to member variables -- is provided by Eiffel directly.
C++ does not provide that facility.

 It also fails to provide const inheritance and a thousand
other useful things.

 The way I am forced to look at this is that if you
can do it -- even if it is a bit clumbsy -- then you have no
case for an extension.

 This is because there are far too many things that you CANNOT
do that you need to -- they're more important (IMHO) than things
you CAN do but which would be best achieved by using a code generator.

[Two things that cannot (effectively) be emulated are coroutines
and nested functions. Replacing those is NOT just a localised
change, but requires gross and global transformation of your
whole program. The same applies to dynamic linkage, threads,
garbage collection, and other major functional components
missing from C++. But we have to start somewhere.]

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: jonathan@cae.ca (Jonathan Hutchinson)
Date: 1995/06/09
Raw View
Ben Aveling (bena@triode.apana.org.au) wrote:
: John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
: : Ben Aveling <bena@triode.apana.org.au> wrote:

: : >My biggest complaint about C++ is that a class can't easily export
: : >read-only variables to the general public.

: :  Sure it can. Two ways at least:

: :  class X { int i;
: :  public:
: :   int const &geti()const {
: :    return const_cast<X*>(this)->i;

: That's easy?  I realize it'll optimize away, but it's a lot of code for
: nix.  Plus a lot of extra names - I don't want to have to add an extra
: function and function name for everything I want to make visible.

: :   int const &j;

: That doesn't count - I still want it read/write inside my class.

: :   }
: :   X() : j(i) {}
: :  }


Is it possible to create a public const variable that is set to a
proivate non-const variable, thereby giving the user's of the class
a readonly view of the variable, while members and friends have a
modifiable version?

I know the following code does not work, but is there a way to get
the result it is attempting to achieve?



class TestIt
{

    int modifiable; // internal non-const variable

public:
    int &const non_modifable = modifiable;  // external scope
         // non modifiable version

};

BTW, the non_modifable variable is supposed to be a reference to an
int that is const (not the int, but the reference) Does that make any
sense. the const is supposed to ensure that the original int will not
be modified by the reference version...

Just a shot in the dark.

Jonathan Hutchinson

jonathan@cae.ca






Author: jonathan@cae.ca (Jonathan Hutchinson)
Date: 1995/06/09
Raw View
Jonathan Hutchinson (jonathan@cae.ca) wrote:

: Is it possible to create a public const variable that is set to a
: proivate non-const variable, thereby giving the user's of the class
: a readonly view of the variable, while members and friends have a
: modifiable version?

: I know the following code does not work, but is there a way to get
: the result it is attempting to achieve?


Well, I just took the time to test my idea, and sure enough it works.

Here is the code:


[code begins]

#include <iostream.h>

class Jon
{

    int writeable;

public:
    int  const &readonly;
    Jon(int i) : readonly(writeable) { writeable = i;}

    void set(int i) {writeable = i;}
    int get() {return writeable;}

    ~Jon() {}

};


main()
{

    Jon jon(10);

    cout << "Value of writeable : " <<  jon.get() << '\n';
    cout << "Value of readable  : " <<  jon.readonly << '\n';

    cout << "calling jon.set(15) \n";
    jon.set(15);
    cout << "Value of writeable : " <<  jon.get() << '\n';
    cout << "Value of readable  : " <<  jon.readonly << '\n';

//    cout << "calling jon.readonly = 15 \n";
//   jon.readonly = 15;
//    cout << "Value of writeable : " <<  jon.get() << '\n';
//    cout << "Value of readable  : " <<  jon.readonly << '\n';

    return 0;

}


[end code]

The four lines of code commented out will cause a compiler error
like the following (on DEC Alpha) :

" jon.cxx:95: error: In this statement, "jon.readonly" has
  const-qualified type, but occurs in a context that requires a
  modifiable lvalue. "


So, it is not *too* complicated to have a variable that is const
to the outside world, but writable for members and friends. Try
the code, it should just cut and paste.

Jonathan Hutchinson

jonathan@cae.ca






Author: joshua@oncomdis.on.ca (joshua)
Date: 1995/06/10
Raw View
Stephen Williams (steve@spokane.ia-us.com) wrote:
: That compiler would be in error:

: 6 For an enumeration where emin is the smallest enumerator and  emax  is
:   the  largest,  the  values  of  the  enumeration are the values of the
:   underlying type in the range bmin to bmax, where bmin  and  bmax  are,
:   respectively,  the  smallest  and  largest values of the smallest bit-
:   field that can store emin and emax.

: All the intermediate numbers are valid enumeration values, even though
: they do not have a name.

Boy, that's a new one!  The ONLY valid values for an enum are in it's
definition, otherwise why bother having enums as all?

I'd like to know where you heard otherwise.

-- Joshua Allen
joshua@oncomdis.on.ca





Author: imp@village.org (Warner Losh)
Date: 1995/06/11
Raw View
In article <3rdg23$70@oncomdis.on.ca>, joshua <joshua@oncomdis.on.ca> wrote:
>Boy, that's a new one!  The ONLY valid values for an enum are in it's
>definition, otherwise why bother having enums as all?

Consider the following enum:

enum Bits { a = 1, b = 2, c = 4, d = 8 };

It is acceptible to do the following:
 Bits b = (Bits) a | b | c;

This is a *VERY* common practice.

In fact, the quoted section of the draft standard makes this clear.

Where did you get the idea that the only valid values for an enum are
in its definition?

Warner
--
Warner Losh  "VMS Forever"  home: imp@village.org
Cyberspace Development, Inc   work: imp@marketplace.com
Makers of TIA, The Internet Adapter.  http://marketplace.com/





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/06/11
Raw View
>>>>> joshua  <joshua@oncomdis.on.ca> writes:

> Stephen Williams (steve@spokane.ia-us.com) wrote:
> : That compiler would be in error:

> : 6 For an enumeration where emin is the smallest enumerator and  emax  is
> :   the  largest,  the  values  of  the  enumeration are the values of the
> :   underlying type in the range bmin to bmax, where bmin  and  bmax  are,
> :   respectively,  the  smallest  and  largest values of the smallest bit-
> :   field that can store emin and emax.

> : All the intermediate numbers are valid enumeration values, even though
> : they do not have a name.

> Boy, that's a new one!  The ONLY valid values for an enum are in it's
> definition

> I'd like to know where you heard otherwise.

Weeeeeeeeeeeell, that would be the public review C++ Working Paper.  You
might look at "http://www.cygnus.com/~mrs/wp-draft/dcl.html#dcl.enum"
before you start mocking people.

> otherwise why bother having enums as all?

If you like, you can document that variables of enum types that you define
must only contain the values that you specify.  Some people like to use
enumerators as bitmasks.

Jason





Author: porter@mu.enet.dec.com (dave porter)
Date: 1995/06/08
Raw View
In re:

: >The realy smart compiler will work out that for
: >enum { a, b, c. WorkArround=9999999 }
: >  that it only needs a char to implement this enum. It stores
: >  127 for the WorkAround value and when converting the enum to int  maps 127 to
: >  9999999 and when converting int to the enum maps 9999999 to 127.

: I don't think that is permitted.  From the draft spec, ......

bkline@cortex.nlm.nih.gov (Bob Kline Phoenix Contract) wrote:

> Nor is it desirable.  Too much existing code relies on enumeration
> values used as bitmasks.

But how could you tell?  I assume that any context which used
an enum value as a bitmask would actually convert the enum to
an int, thus undoing the "enum compression".

This doesn't think I mean that the scheme is a good one nor
that I believe it is permitted by the language spec; I'm just
nit-picking :-)











Author: joshua@oncomdis.on.ca (joshua)
Date: 1995/06/08
Raw View
I'll give a clean answer to the questions in this thread:
(it got really muddy)

the only (portable) way to know the real size of an enum
is to use sizeof(enum_name)

you can't predict what the size of an enum will be from
the values in it's definition

-- Joshua Allen
joshua@oncomdis.on.ca





Author: Andrew Cheshire <andy@axiomati.demon.co.uk>
Date: 1995/06/08
Raw View
In article: <3r53f9$fi8@larry.rice.edu>  cgh@noel.cs.rice.edu (Christopher G. Hyams) writes:
>
> Jason Merrill (jason@cygnus.com) wrote:
> : >>>>> Ben Aveling <bena@triode.apana.org.au> writes:
>
> : > John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
> : > : Ben Aveling <bena@triode.apana.org.au> wrote:
>
> : > : >My biggest complaint about C++ is that a class can't easily export
> : > : >read-only variables to the general public.
>
> [... snip ...]
>
> Why not just:
>
> class foo {
> public:
>   \\ ...
>   const int& i() const { return i; }
> private:
>   \\ ...
>   int i;
> };
>
> It's the same name.  What more could you want?
> --


The use of the same identifier for a data member and a function member is not legal.

Unless it's a recent addition to the standard, in which case excuse my ignorance.

----------------------------------------------
Andrew Cheshire      andy@axiomati.demon.co.uk
Axiomatic Software   CIS: 100273,154
"i forgive you molesworth for those uncouth words"






Author: bena@triode.apana.org.au (Ben Aveling)
Date: 1995/06/07
Raw View
John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
: Ben Aveling <bena@triode.apana.org.au> wrote:

: >My biggest complaint about C++ is that a class can't easily export
: >read-only variables to the general public.

:  Sure it can. Two ways at least:

:  class X { int i;
:  public:
:   int const &geti()const {
:    return const_cast<X*>(this)->i;

That's easy?  I realize it'll optimize away, but it's a lot of code for
nix.  Plus a lot of extra names - I don't want to have to add an extra
function and function name for everything I want to make visible.

:   int const &j;

That doesn't count - I still want it read/write inside my class.

:   }
:   X() : j(i) {}
:  }

What I want to do is something like  (Pls excuse non C++ like grammer)

Class  SteamPoweredEngine
{
    Needle PressureGuage internal_scope writeonly, external_scope readonly.
    Lever  Throttle      internal_scope readonly, external_scope readwrite.
    ...
};

An external write only variable might be an entry in a request queue,
and so on.

OK, all of these things can be done by overloading operators, but
let's put it this way;  Who here wouldn't like to be able to easily
specify a variable's visibility with the sort of precision I've used
in my example?

    Regards, Ben





Author: cgh@noel.cs.rice.edu (Christopher G. Hyams)
Date: 1995/06/07
Raw View
Jason Merrill (jason@cygnus.com) wrote:
: >>>>> Ben Aveling <bena@triode.apana.org.au> writes:

: > John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
: > : Ben Aveling <bena@triode.apana.org.au> wrote:

: > : >My biggest complaint about C++ is that a class can't easily export
: > : >read-only variables to the general public.

: > :  Sure it can. Two ways at least:

: > :  class X { int i;
: > :  public:
: > :   int const &geti()const {
: > :    return const_cast<X*>(this)->i;

: > That's easy?  I realize it'll optimize away, but it's a lot of code for
: > nix.  Plus a lot of extra names - I don't want to have to add an extra
: > function and function name for everything I want to make visible.

: It's unnecessarily complex;

:          int const &geti() const { return i; }

: will do just as well.  Extra names?  Oh, well.

: Jason

Why not just:

class foo {
public:
  \\ ...
  const int& i() const { return i; }
private:
  \\ ...
  int i;
};

It's the same name.  What more could you want?
--
Chris Hyams
cgh@cs.rice.edu
http://www.cs.rice.edu/~cgh/





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/06/07
Raw View
>>>>> Christopher G Hyams <cgh@noel.cs.rice.edu> writes:

> Why not just:

> class foo {
> public:
>   \\ ...
>   const int& i() const { return i; }
> private:
>   \\ ...
>   int i;
> };

> It's the same name.  What more could you want?

Mmm...portable code?  Your example is ill-formed.  A method may not have
the same name as a data member.

Jason





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/06/07
Raw View
>>>>> Ben Aveling <bena@triode.apana.org.au> writes:

> John Max Skaller (maxtal@Physics.usyd.edu.au) wrote:
> : Ben Aveling <bena@triode.apana.org.au> wrote:

> : >My biggest complaint about C++ is that a class can't easily export
> : >read-only variables to the general public.

> :  Sure it can. Two ways at least:

> :  class X { int i;
> :  public:
> :   int const &geti()const {
> :    return const_cast<X*>(this)->i;

> That's easy?  I realize it'll optimize away, but it's a lot of code for
> nix.  Plus a lot of extra names - I don't want to have to add an extra
> function and function name for everything I want to make visible.

It's unnecessarily complex;

         int const &geti() const { return i; }

will do just as well.  Extra names?  Oh, well.

Jason





Author: joshua@oncomdis.on.ca (joshua)
Date: 1995/06/05
Raw View
Stephen Baynes (baynes@ukpsshp1.serigate.philips.nl) wrote:
: Jimmy Alamparambil (jimmya@dgp.toronto.edu) wrote:

: : Suppose you have :

: : enum numbers {ONE,TWO,THREE,FOUR};
: : numbers digit;
: : digit = ONE;
: : digit++;

: : Should there be a compile error on the "digit++" statement?
: : A C++ tutorial I have says there should be no error.
: : Watcom C++ 9.5 gives an error: variable is not assigned a valid enumerated
: :                                value.

: In my view if the standard prohibits the use of ++ and -- on enums (which is
: what now seems to be the case) then that is a bad decision by the standard
: makers. It is often necessary to itterate over a enumerated type.

You can overload any of the operators (including ++ and --) for
your enums.

Off hand I think this would be:

numbers operator++(number i) {
 switch(i) {
 case ONE: return TWO;
 case TWO: return THREE;
 case THREE: return FOUR;
 default: throw "Invalid value for a numbers in operator++";
 }
}

You can do a number of things with default or for a value of FOUR.

-- Joshua Allen
joshua@oncomdis.on.ca






Author: steve@spokane.ia-us.com (Stephen Williams)
Date: 1995/06/05
Raw View
In article <D9HsqI.KHE@ukpsshp1.serigate.philips.nl> baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes:

   The realy smart compiler will work out that for
   enum { a, b, c. WorkArround=9999999 }
     that it only needs a char to implement this enum. It stores
     127 for the WorkAround value and when converting the enum to int  maps 127 to
     9999999 and when converting int to the enum maps 9999999 to 127.


That compiler would be in error:

6 For an enumeration where emin is the smallest enumerator and  emax  is
  the  largest,  the  values  of  the  enumeration are the values of the
  underlying type in the range bmin to bmax, where bmin  and  bmax  are,
  respectively,  the  smallest  and  largest values of the smallest bit-
  field that can store emin and emax.

All the intermediate numbers are valid enumeration values, even though
they do not have a name.

--

Stephen 2. Williams
 Work: steve@ia-us.com
 Home: steve@icarus.com

    Fight License Managers! Buy from
    vendors who use honor system!





Author: rad6938@gemini.tntech.edu (Rad)
Date: 1995/06/05
Raw View
In article <D9HsqI.KHE@ukpsshp1.serigate.philips.nl>, baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes:
>Ben Aveling (bena@triode.apana.org.au) wrote:
>: Mike McCormick (mtm4@rsvl.unisys.com) wrote:
>
>: : So the answer depends on your compiler.  We have one compiler which just
>: : generates an INT under all ENUMs.  We have another which generates SHORT INT
>: : unless one of the values in the enumerated set is too big for a short.
>
>: : To get these different compilers to share common header files containing
>: : ENUMs, we have had to resort to defining a dummy value workAround1=9999999,
>: : workAround2=9999999, etc. in each ENUM to force the smarter compiler to
>: : generate full size INT so it can share data structures with the the dumber one!
>
>: IMHO the _smarter_ compiler is the one which always uses the same size
>: for enums.  Clever != Smart.
>
>The realy smart compiler will work out that for
>enum { a, b, c. WorkArround=9999999 }
>  that it only needs a char to implement this enum. It stores
>  127 for the WorkAround value and when converting the enum to int  maps 127 to
>  9999999 and when converting int to the enum maps 9999999 to 127.

I don't think this would conforming.  I believe the standard requires the
representation of an enum to be able to hold all integer values through the max
value used.  (In fact I think it has to even hold some past that if the max
isn't one less then a power of two.)

----------------------------------------------------------------------------
 Richard Deken                   Graduate student in electrical engineering
 PGP public key available      Tennessee Technological University
 Internet: rad6938@gemini.tntech.edu        Cookeville, TN, USA





Author: bkline@cortex.nlm.nih.gov (Bob Kline Phoenix Contract)
Date: 1995/06/06
Raw View
Barry Margolin (barmar@nic.near.net) wrote:
: In article <D9HsqI.KHE@ukpsshp1.serigate.philips.nl> baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes:
: >The realy smart compiler will work out that for
: >enum { a, b, c. WorkArround=9999999 }
: >  that it only needs a char to implement this enum. It stores
: >  127 for the WorkAround value and when converting the enum to int  maps 127 to
: >  9999999 and when converting int to the enum maps 9999999 to 127.

: I don't think that is permitted.  From the draft spec, ......

Nor is it desirable.  Too much existing code relies on enumeration
values used as bitmasks.

--
/*----------------------------------------------------------------------*/
/* Bob Kline                                       Stream International */
/* bob_kline@stream.com               formerly Corporate Software, Inc. */
/* voice: (703) 522-0820 x-311                      fax: (703) 522-5407 */
/*----------------------------------------------------------------------*/





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/06/04
Raw View
In article <D9JBKx.3xt@ukpsshp1.serigate.philips.nl>,
Stephen Baynes <baynes@ukpsshp1.serigate.philips.nl> wrote:

[digit is an enum]

>: digit++;
>
>I think that this is something that has changed in the life of C++. This
>was originally allowed but modern compilers now reject it. This one cost
>me quite a bit of rewriting when I had to port some code from an older
>C++ compiler to a new one (and not the only thing).
>
>You can use :
>        digit = (numbers) ( digit + 1 );
>
>In my view if the standard prohibits the use of ++ and -- on enums (which is
>what now seems to be the case) then that is a bad decision by the standard
>makers. It is often necessary to itterate over a enumerated type.

 Something _else_ changed to compensate, Stephen. enums are
now also first class types -- you can overload on them. So you can
write:

 template<class T> void operator++(T& t) { t = (T) (t+1); }
 // or variation thereof

and suddenly all your enums++ work again.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes)
Date: 1995/06/02
Raw View
Jimmy Alamparambil (jimmya@dgp.toronto.edu) wrote:

: This question is simple, yet seems related to this thread...

: Suppose you have :

: enum numbers {ONE,TWO,THREE,FOUR};

: numbers digit;
: digit = ONE;

: digit++;

: Should there be a compile error on the "digit++" statement?
: A C++ tutorial I have says there should be no error.
: Watcom C++ 9.5 gives an error: variable is not assigned a valid enumerated
:                                value.

: Whats right, and according to whom?

I think that this is something that has changed in the life of C++. This
was originally allowed but modern compilers now reject it. This one cost
me quite a bit of rewriting when I had to port some code from an older
C++ compiler to a new one (and not the only thing).

You can use :
        digit = (numbers) ( digit + 1 );

In my view if the standard prohibits the use of ++ and -- on enums (which is
what now seems to be the case) then that is a bad decision by the standard
makers. It is often necessary to itterate over a enumerated type.

--
Stephen Baynes                              baynes@mulsoc2.serigate.philips.nl
Philips Semiconductors Ltd
Southampton                                 My views are my own.
United Kingdom





Author: baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes)
Date: 1995/06/01
Raw View
Ben Aveling (bena@triode.apana.org.au) wrote:
: Mike McCormick (mtm4@rsvl.unisys.com) wrote:

: : So the answer depends on your compiler.  We have one compiler which just
: : generates an INT under all ENUMs.  We have another which generates SHORT INT
: : unless one of the values in the enumerated set is too big for a short.

: : To get these different compilers to share common header files containing
: : ENUMs, we have had to resort to defining a dummy value workAround1=9999999,
: : workAround2=9999999, etc. in each ENUM to force the smarter compiler to
: : generate full size INT so it can share data structures with the the dumber one!

: IMHO the _smarter_ compiler is the one which always uses the same size
: for enums.  Clever != Smart.

The realy smart compiler will work out that for
enum { a, b, c. WorkArround=9999999 }
  that it only needs a char to implement this enum. It stores
  127 for the WorkAround value and when converting the enum to int  maps 127 to
  9999999 and when converting int to the enum maps 9999999 to 127.



--
Stephen Baynes                              baynes@mulsoc2.serigate.philips.nl
Philips Semiconductors Ltd
Southampton                                 My views are my own.
United Kingdom





Author: barmar@nic.near.net (Barry Margolin)
Date: 1995/06/01
Raw View
In article <D9HsqI.KHE@ukpsshp1.serigate.philips.nl> baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes:
>The realy smart compiler will work out that for
>enum { a, b, c. WorkArround=9999999 }
>  that it only needs a char to implement this enum. It stores
>  127 for the WorkAround value and when converting the enum to int  maps 127 to
>  9999999 and when converting int to the enum maps 9999999 to 127.

I don't think that is permitted.  From the draft spec, section dcl.enum:

--------------------
6 For  an  enumeration where emin is the smallest enumerator and emax is
  the largest, the values of the  enumeration  are  the  values  of  the
  underlying  type  in  the range bmin to bmax, where bmin and bmax are,
  respectively, the smallest and largest values  of  the  smallest  bit-
  field  that  can  store emin and emax.  On a two's-complement machine,
  bmax   is   the   smallest   value   greater   than   or   equal    to
  max(abs(emin)-1,abs(emax))  of  the form 2M-1; bmin is zero if emin is
  non-negative and -(bmax+1) otherwise.  It is  possible  to  define  an
  enumeration that has values not defined by any of its enumerators.

...

9 An expression of arithmetic or enumeration type or of type wchar_t can
  be  converted  to  an  enumeration  type  explicitly.   The  value  is
  unchanged if it is in the range of enumeration values of the  enumera-
  tion type; otherwise the resulting enumeration value is unspecified.
--------------------

I believe "the range of enumeration values" refers to the range bmin to
bmax, not just the values explicitly specified in the enumeration
declaration (although it's presumably implementation-defined if you use a
value outside emin..emax, since bmin and bmax depend on the binary
representation of the implementation).  So if you do:

enum myenum {a, b, c, large=9999999 } x;
int i;

x = (myenum) 127;
i = x;

--
Barry Margolin
BBN Planet Corporation, Cambridge, MA
barmar@{bbnplanet.com,near.net,nic.near.net,netcom.com}
Phone (617) 873-3126 - Fax (617) 873-5124





Author: jimmya@dgp.toronto.edu (Jimmy Alamparambil)
Date: 1995/06/01
Raw View
This question is simple, yet seems related to this thread...

Suppose you have :

enum numbers {ONE,TWO,THREE,FOUR};

numbers digit;
digit = ONE;

digit++;

Should there be a compile error on the "digit++" statement?
A C++ tutorial I have says there should be no error.
Watcom C++ 9.5 gives an error: variable is not assigned a valid enumerated
                               value.

Whats right, and according to whom?

Thanks for your help.

Jim.






Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/05/30
Raw View
In article <3qc9kv$ffg@triode.apana.org.au>,
Ben Aveling <bena@triode.apana.org.au> wrote:
>
>My biggest complaint about C++ is that a class can't easily export
>read-only variables to the general public.

 Sure it can. Two ways at least:

 class X { int i;
 public:
  int const &j;
  int const &geti()const {
   return const_cast<X*>(this)->i;
  }
  X() : j(i) {}
 }

 X x; int k;
 k= x.j; // OK
 k= x.geti(); // OK
 x.j = 1; // error
 x.geti() = 1; // error

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: bena@triode.apana.org.au (Ben Aveling)
Date: 1995/05/29
Raw View
Mike McCormick (mtm4@rsvl.unisys.com) wrote:

: So the answer depends on your compiler.  We have one compiler which just
: generates an INT under all ENUMs.  We have another which generates SHORT INT
: unless one of the values in the enumerated set is too big for a short.

: To get these different compilers to share common header files containing
: ENUMs, we have had to resort to defining a dummy value workAround1=9999999,
: workAround2=9999999, etc. in each ENUM to force the smarter compiler to
: generate full size INT so it can share data structures with the the dumber one!

IMHO the _smarter_ compiler is the one which always uses the same size
for enums.  Clever != Smart.

: BTW, this is one of many reasons why I am dissatisfied with ENUM.
: the namespace is global (two ENUMs cannot use the same label in their sets),
Agreed!  But they're still a good thing, they just oughta be better.

My biggest complaint about C++ is that a class can't easily export
read-only variables to the general public.

But that's another thread.

    Reagrds, Ben





Author: mike@if.com (MIke Homyack - System Owner)
Date: 1995/05/30
Raw View
On 29 May 1995 11:02:55 GMT, Ben Aveling (bena@triode.apana.org.au) wrote:
 - Mike McCormick (mtm4@rsvl.unisys.com) wrote:

 - : So the answer depends on your compiler.  We have one compiler which just
 - : generates an INT under all ENUMs.  We have another which generates SHORT INT
 - : unless one of the values in the enumerated set is too big for a short.

 - : To get these different compilers to share common header files containing
 - : ENUMs, we have had to resort to defining a dummy value workAround1=9999999,
 - : workAround2=9999999, etc. in each ENUM to force the smarter compiler to
 - : generate full size INT so it can share data structures with the the dumber one!

 - IMHO the _smarter_ compiler is the one which always uses the same size
 - for enums.  Clever != Smart.

IMHO there is no reason that you shouldn't be able to specify the storage used
for a given enumerated type.  If it makes the language more powerful and
extensible, without adding undue complexity, why not do it?

 - : BTW, this is one of many reasons why I am dissatisfied with ENUM.
 - : the namespace is global (two ENUMs cannot use the same label in their sets),
 - Agreed!  But they're still a good thing, they just oughta be better.

 - My biggest complaint about C++ is that a class can't easily export
 - read-only variables to the general public.

 - But that's another thread.

I realize that this is out of place in this tread, but why not just create a
publicly available, constant reference in the class?  That way you store a
single value, it's available to the public and it's read only.  Really just
a one-liner.

 -     Reagrds, Ben

--
== === =    == === =============================================================
==  =  = === = === ==  Mr.H (mike@mrhappy.if.com)                             ==
== = = =    ==     ==  All opinions expressed herein are mine alone... right? ==
== === = === = === ==  "Goodbye boys!" ... "Have fun storming the castle!"    ==
== === = === = === =============================================================
All mail accepted...   Encrypted mail preferred...   E-Mail me for my public key
PGP fingerprint:  CC BD FD 38 BD C2 FB 56  02 AA 3C 7A 68 BB AF 54





Author: mtm4@rsvl.unisys.com (Mike McCormick)
Date: 1995/05/22
Raw View
In article <3pfta3$qqg@news.bbt.com> bk@gateway.bbt.com (B. Kumar) writes:
>From: bk@gateway.bbt.com (B. Kumar)
>Subject: enum size
>Date: 18 May 1995 16:40:35 GMT

>Is there a way to force an enum definition to be a certain size.
>For example, I want to list all types of messages in my application
>in an enumeration like,

>        enum MessageType {
>            Command,
>            Response
>        };

>The structure that another application uses for these messages include
>a message type that is a short.  So I want to have a similar structure

According to the ANSI standard, and as explained by Stroustrup in his 2nd
Edition, the size of the underlying type behind ENUM is implementation
dependent, as long as it conforms to the rule that it promotes to INT and is
no larger than INT.

So the answer depends on your compiler.  We have one compiler which just
generates an INT under all ENUMs.  We have another which generates SHORT INT
unless one of the values in the enumerated set is too big for a short.

To get these different compilers to share common header files containing
ENUMs, we have had to resort to defining a dummy value workAround1=9999999,
workAround2=9999999, etc. in each ENUM to force the smarter compiler to
generate full size INT so it can share data structures with the the dumber one!

BTW, this is one of many reasons why I am dissatisfied with ENUM.  The type
checking is not all that great (definitions outside an ENUM's set are legal),
the namespace is global (two ENUMs cannot use the same label in their sets),
the sizeof() is unpredictable as described above, etc.  IMHO C++ missed a
great opportunity to improve ENUM, which was passed over (like so many good
ideas in C++) in the name of C Compatibility.


------------------------------------------------------------------
 Mike McCormick
 mtm4@rsvl.unisys.com
 m.mccormick2@genie.geis.com
------------------------------------------------------------------
 While you're out surfing the internet...
 I'm back on the beach blowing my little lifeguard whistle.
------------------------------------------------------------------





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/05/22
Raw View
In article 00FA24F8@rsvl.unisys.com, mtm4@rsvl.unisys.com (Mike McCormick) writes:
>
>According to the ANSI standard, and as explained by Stroustrup in his 2nd
>Edition, the size of the underlying type behind ENUM is implementation
>dependent, as long as it conforms to the rule that it promotes to INT and is
>no larger than INT.

The current draft of the standard allows long values for enums, and so
an enum can be the size of a long.

>So the answer depends on your compiler.  We have one compiler which just
>generates an INT under all ENUMs.  We have another which generates SHORT INT
>unless one of the values in the enumerated set is too big for a short.
>
>To get these different compilers to share common header files containing
>ENUMs, we have had to resort to defining a dummy value workAround1=9999999,
>workAround2=9999999, etc. in each ENUM to force the smarter compiler to
>generate full size INT so it can share data structures with the the dumber one!

In the absense of a platform ABI for C++, you may find differences among
compilers other than the size of an enum. Struct padding and minimum
struct size may vary as well, for example. If the platform does have a C++
ABI, it must specify the size(s) of enums, and compilers should have a
mode whereby they comply with the ABI.


>BTW, this is one of many reasons why I am dissatisfied with ENUM.  The type
>checking is not all that great (definitions outside an ENUM's set are legal),

That is a deliberate design decision to allow enums to be extended. You
don't have to like it, I suppose.

>the namespace is global (two ENUMs cannot use the same label in their sets),

The namespace isn't global. The enumerators are in the same namespace as the
enum type itself. That is consistent with enums in some other languages,
although different designs are possible. You can always put each enum into
its own class or namespace and get scoped enumerators. That is,
instead of this:
 enum Status { bad, ugly, good, splendid };
do this:
 namespace Status { enum { bad, ugly, good, splendid }; }
Now you have to say Status::good, which is presumably what you prefer.

>the sizeof() is unpredictable as described above, etc.

So is sizeof(int), sizeof(double), sizeof(struct_with_odd_number_of_bytes), etc.

>  IMHO C++ missed a
>great opportunity to improve ENUM, which was passed over (like so many good
>ideas in C++) in the name of C Compatibility.

Not so. Enums in C are not very compatible with enums in C++. Code which
is valid and well-defined in one language is not necessarily so in the other.
(The incompatibilities now go in both directions.)
---
Steve Clamage, stephen.clamage@eng.sun.com