Topic: forward declaration of enum types?
Author: sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1998/05/19 Raw View
>Who knows, how I can make a forward declaration of an enum type in a
>headerfile? This would be useful, if you have a function prototype in
>your headerfile with the enum type needed as parameter and you don't
>want to include a huge third party headerfile only for this type.
>(Including in the implementation *.C file reduces the dependencies of
>other files including your smaller headerfile).
This is what I do.
// enumClass.h
struct enumClass
{
enum Greek { ALPHA, BETA, GAMMA };
};
// Class.h
#include <enumClass.h>
class Class : public enumClass, ... { ... };
// file.c
#include <enumClass.h> // no need to include Class.h
This helps me with me with insulation.
Of course, put (redundant) include guards.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Joe Keane <jgk@jgk.org>
Date: 1998/05/21 Raw View
In article <bill-1505980928410001@bgibbons.vip.best.com>
Bill Gibbons <bill@gibbons.org> writes:
>Tentative (forward) declarations of enums would allow for slightly better
>hiding of implementation details. Whether the improvement would justify
>the trivial increase in the complexity of the language is a matter of
>opinion. In my opinion, it would have been justified.
The change is good, and you can argue that it simplifies the language,
since it makes `enum' follow the same rules as `struct' and `union'.
For example, with an undefined `enum', you can't declare a variable or
field of that type, but you can always use a pointer to it no problem.
--
Joe Keane, amateur mathematician
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/11 Raw View
Steve Clamage wrote:
>=20
> In article 15FB@wizard.net, James Kuyper <kuyper@wizard.net> writes:
> >Steve Clamage wrote:
> >>
> >> 2. It is never necessary to forward-declare an enum. It is necessary
> >> to forward-declare a class to allow cross-referencing. Enums cannot
> >> cross-reference, so no forward declaration is needed for that
> >> reason.
> >>
> >> If you want to declare an enum and defer definition of some of
> >> its enumerators until later, you can do that without a forward
> >> declaration. Example:
> >>
> >> enum spicyness { bland=3D0, lethal=3D2000 };
> >> ...
> >> const spicyness mild =3D spicyness(100);
> >> const spicyness hot =3D spicyness(500);
> >> // etc
> >>
> >> You can now use "mild" and "hot" as if they were part of the
> >> original enum definition.
> >
> >However, per section 7.2, paragraph 9, the values of 'mild' and 'hot'
> >are unspecified. In particular, they needn't compare equal to 100 and
> >500 respectively, and they needn't be distinct from 'bland', or
> >'lethal', or each other. Of course, 100 and 500 are the most reasonab=
le
> >values, but you shouldn't count on them.
>=20
> I don't understand how you can interpret that paragraph to have such
> a meaning. Section 7.2 requires exactly what I said. Here is paragraph =
9:
>=20
> "An expression of arithmetic or enumeration type can be converted to an
> enumeration type explicitly. The value is UNCHANGED if it is in the ran=
ge
> of enumeration values of the enumeration type; otherwise the resulting
> enumeration value is unspecified." [uppercase is mine]
>=20
> The "range" of the enumeration is defined in paragraph 6:
> "For an enumeration where emin is the smallest enumerator and emax is t=
he
> 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=ADfield that can st=
ore
> emin and emax. It is possible to define an enumeration that has values
> not defined by any of its enumerators."
My apologies; I took "range of enumeration values" as being equivalent
to "enumeration list", and I was in too much of a hurry to verify that
interpretation. I knew C++ enforces type-safe code more strongly than C
in many ways, and I thought I'd found another one.
Even if this is legal code, I still don't think it's good code, but
that's a different issue.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/05/13 Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
>Steve Clamage wrote:
>>
>> 1. You couldn't do anything with the enum except declare pointers
>> or references to it, since the compiler doesn't know the size of
>> the enum until it sees the definition. (Different enums are
>> allowed to be different sizes.)
>There's nothing in the standard that would prevent a compiler from
>assuming a forward-referenced enum to be the largest legal size for an
>enum, and simply forego the opportunity to use something smaller if it
>later turns out to be possible. In fact, I suppose it could even assume
>it to be the size of an int, and then complain later if it an enumerator
>is defined that doesn't fit into an int.
Now suppose you forward-declare the enum in one compilation unit
and define it in another. The compiler can't know it should
allocate the fixed size in the unit where it wasn't forward-declared.
It would have to be considered a violation of the One-Definition
Rule, with undefined results, and no diagnosis required. IMHO that
is not a good tradeoff for the ability to forward-declare enums.
I see only two reasonable possibilities:
1. Enums have a fixed size.
2. Enums can't be forward-declared.
C++ has the second rule. I still don't see any significant benefit
to being able to forward-declare enums.
--
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: bill@amber.ssd.csd.harris.com (Bill Leonard)
Date: 1998/05/13 Raw View
In article <6jbhgo$s6l@engnews1.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve Clamage) writes:
> Now suppose you forward-declare the enum in one compilation unit
> and define it in another. The compiler can't know it should
> allocate the fixed size in the unit where it wasn't forward-declared.
> I see only two reasonable possibilities:
> 1. Enums have a fixed size.
> 2. Enums can't be forward-declared.
Well, I can think of other possibilities. For example, you could restrict
where a forward-declared enum type could be used. You could disallow it
being used to declare a variable, but allow it to be used to declare a
pointer, a reference, or a function return value. Function return values
could be allowed because, typically, an implementation will (or could)
return any integer type as a "full sized" int.
This might require an implementation to always return enum values as a
fixed size, but that's not too unreasonable, in my opinion.
> C++ has the second rule. I still don't see any significant benefit
> to being able to forward-declare enums.
Well, I can think of one. Suppose you have a class with member functions
that are going to return enum values. The class declaration does not need
to know the specific enum constants, it only needs to know the name of the
type and its "representation".
Now suppose that this enum type undergoes fairly frequent revision; that is,
constants are added or removed frequently. And suppose that this class,
which has member functions returning these enum values, is referenced in
lots of places in the program. If you require that the class include
the full definition of the enum, you get lots of recompilation; but if
you could just use a forward declaration for the class, you would get less
recompilation.
This is analogous to cases where struct and class types are forward
declared in include files for class declarations, and only really defined
in the class definitions and in users of the class. This helps avoid
needless recompilations.
--
Bill Leonard
Concurrent Computer Corporation
2101 W. Cypress Creek Road
Fort Lauderdale, FL 33309
Bill.Leonard@mail.ccur.com
These opinions and statements are my own and do not necessarily reflect the
opinions or positions of Concurrent Computer Corporation.
------------------------------------------------------------------------------
It doesn't matter which way you are headed if you're not going anywhere.
------------------------------------------------------------------------------
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/05/13 Raw View
In article hq0@hawk-hcsc.hcsc.com, bill@amber.ssd.csd.harris.com (Bill Leonard) writes:
>In article <6jbhgo$s6l@engnews1.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve Clamage) writes:
>> Now suppose you forward-declare the enum in one compilation unit
>> and define it in another. The compiler can't know it should
>> allocate the fixed size in the unit where it wasn't forward-declared.
>
>> I see only two reasonable possibilities:
>> 1. Enums have a fixed size.
>> 2. Enums can't be forward-declared.
>
>Well, I can think of other possibilities. For example, you could restrict
>where a forward-declared enum type could be used. You could disallow it
>being used to declare a variable, but allow it to be used to declare a
>pointer, a reference, or a function return value. Function return values
>could be allowed because, typically, an implementation will (or could)
>return any integer type as a "full sized" int.
Notice I said "reasonable" possibilities. If you allow calling a
function that has only a forward-declared return type, you have
the same problem I outlined above. An enum is allowed to be bigger
than an int, so assuming int size won't work (in general -- longs
are bigger than ints on some systems). You are back to requiring
fixed size for enums as part of the language definition.
You could make the same restrictions as for classes: you could use
(but not dereference) pointers and references, and that's all.
I *still* don't find that useful for enums, given the low overhead
for processing typical enum definitions.
>This might require an implementation to always return enum values as a
>fixed size, but that's not too unreasonable, in my opinion.
That's a language design issue. I agree requiring a fixed size is
a defensible choice. C++ did not make that choice, mostly because
it conflicts with C, which allows enums to have different sizes.
(There was strong insistence that enums should be capable of being
stored efficiently.)
>> C++ has the second rule. I still don't see any significant benefit
>> to being able to forward-declare enums.
>
>Well, I can think of one. Suppose you have a class with member functions
>that are going to return enum values. The class declaration does not need
>to know the specific enum constants, it only needs to know the name of the
>type and its "representation".
And we're back to requiring fixed size for enums. Otherwise you can't
know the representation.
>Now suppose that this enum type undergoes fairly frequent revision; that is,
>constants are added or removed frequently. And suppose that this class,
>which has member functions returning these enum values, is referenced in
>lots of places in the program. If you require that the class include
>the full definition of the enum, you get lots of recompilation; but if
>you could just use a forward declaration for the class, you would get less
>recompilation.
You can solve that problem with the technique I outlined earlier:
enum E { E_min=0, E_max=65535 };
Then later you can add in another header that doesn't force extensive
recompilation:
E E1 = E(value1);
E E2 = E(value2);
Some people don't like this solution. (It isn't perfect.) I don't
particularly like requiring enums to have a fixed size.
You can't please everyone. :-)
---
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/05/13 Raw View
Steve Clamage wrote:
>
> 1. You couldn't do anything with the enum except declare pointers
> or references to it, since the compiler doesn't know the size of
> the enum until it sees the definition. (Different enums are
> allowed to be different sizes.)
There's nothing in the standard that would prevent a compiler from
assuming a forward-referenced enum to be the largest legal size for an
enum, and simply forego the opportunity to use something smaller if it
later turns out to be possible. In fact, I suppose it could even assume
it to be the size of an int, and then complain later if it an enumerator
is defined that doesn't fit into an int.
--
Ciao,
Paul
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: bill@gibbons.org (Bill Gibbons)
Date: 1998/05/15 Raw View
In article <6jbhgo$s6l@engnews1.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve
Clamage) wrote:
> I see only two reasonable possibilities:
> 1. Enums have a fixed size.
> 2. Enums can't be forward-declared.
And of course:
3. Enums work just like classes - they can be forward-declared, but
there are restrictions on their use if incomplete.
> C++ has the second rule. I still don't see any significant benefit
> to being able to forward-declare enums.
Having worked with a header file which declared the entire Unicode-16
character set as an enum, with over 16,000 names for the various
characters, I can see some benefit in writing interfaces which
pass enums by reference so that they can be foward-declared, avoiding
the need for compiling the entire enumeration in client code.
Also, since enumerator names are declared in the context containing the
enumeration, adding additional names to an enumeration may cause existing
code to stop compiling for no good reason.
Sometimes a type name must be visible but its implementation details
should be hidden. This is especially true for enumerations, since the
enumerator names are visible outside the enum declaration.
Tentative (forward) declarations of enums would allow for slightly better
hiding of implementation details. Whether the improvement would justify
the trivial increase in the complexity of the language is a matter of
opinion. In my opinion, it would have been justified.
-- Bill Gibbons
bill@gibbons.org
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ren Lanz" <rene.lanz@bluewin.ch>
Date: 1998/05/06 Raw View
Hi!
Who knows, how I can make a forward declaration of an enum type in a
headerfile? This would be useful, if you have a function prototype in
your headerfile with the enum type needed as parameter and you don't
want to include a huge third party headerfile only for this type.
(Including in the implementation *.C file reduces the dependencies of
other files including your smaller headerfile).
By the way: typedef int <type> is not the proper way resulting in a
redeclaration of <type> when the *.C file includes both headerfiles...
Thanks for ideas...
Rene
--
+---------------------------------------------------------------------+
| Ren=E9 Lanz Phone : +41 56 496 17 38 |
| Zweierestr. 5d E-Mail : rene.lanz@bluewin.ch |
| CH-5443 Niederrohrdorf |
+---------------------------------------------------------------------+
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/05/08 Raw View
In article 9A62451F@bluewin.ch, "Ren Lanz" <rene.lanz@bluewin.ch> writes:
>
>Who knows, how I can make a forward declaration of an enum type in a
>headerfile?
You can't (not allowed by the language definition), for two reasons:
1. You couldn't do anything with the enum except declare pointers
or references to it, since the compiler doesn't know the size of
the enum until it sees the definition. (Different enums are
allowed to be different sizes.)
2. It is never necessary to forward-declare an enum. It is necessary
to forward-declare a class to allow cross-referencing. Enums cannot
cross-reference, so no forward declaration is needed for that
reason.
If you want to declare an enum and defer definition of some of
its enumerators until later, you can do that without a forward
declaration. Example:
enum spicyness { bland=0, lethal=2000 };
...
const spicyness mild = spicyness(100);
const spicyness hot = spicyness(500);
// etc
You can now use "mild" and "hot" as if they were part of the
original enum definition.
---
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/08 Raw View
Steve Clamage wrote:
>=20
> In article 9A62451F@bluewin.ch, "Ren=E9 Lanz" <rene.lanz@bluewin.ch> wr=
ites:
> >
> >Who knows, how I can make a forward declaration of an enum type in a
> >headerfile?
>=20
> You can't (not allowed by the language definition), for two reasons:
>=20
> 1. You couldn't do anything with the enum except declare pointers
> or references to it, since the compiler doesn't know the size of
> the enum until it sees the definition. (Different enums are
> allowed to be different sizes.)
>=20
> 2. It is never necessary to forward-declare an enum. It is necessary
> to forward-declare a class to allow cross-referencing. Enums cannot
> cross-reference, so no forward declaration is needed for that
> reason.
>=20
> If you want to declare an enum and defer definition of some of
> its enumerators until later, you can do that without a forward
> declaration. Example:
>=20
> enum spicyness { bland=3D0, lethal=3D2000 };
> ...
> const spicyness mild =3D spicyness(100);
> const spicyness hot =3D spicyness(500);
> // etc
>=20
> You can now use "mild" and "hot" as if they were part of the
> original enum definition.
However, per section 7.2, paragraph 9, the values of 'mild' and 'hot'
are unspecified. In particular, they needn't compare equal to 100 and
500 respectively, and they needn't be distinct from 'bland', or
'lethal', or each other. Of course, 100 and 500 are the most reasonable
values, but you shouldn't count on them.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/05/09 Raw View
In article 15FB@wizard.net, James Kuyper <kuyper@wizard.net> writes:
>Steve Clamage wrote:
>>
>> 2. It is never necessary to forward-declare an enum. It is necessary
>> to forward-declare a class to allow cross-referencing. Enums cannot
>> cross-reference, so no forward declaration is needed for that
>> reason.
>>
>> If you want to declare an enum and defer definition of some of
>> its enumerators until later, you can do that without a forward
>> declaration. Example:
>>
>> enum spicyness { bland=0, lethal=2000 };
>> ...
>> const spicyness mild = spicyness(100);
>> const spicyness hot = spicyness(500);
>> // etc
>>
>> You can now use "mild" and "hot" as if they were part of the
>> original enum definition.
>
>However, per section 7.2, paragraph 9, the values of 'mild' and 'hot'
>are unspecified. In particular, they needn't compare equal to 100 and
>500 respectively, and they needn't be distinct from 'bland', or
>'lethal', or each other. Of course, 100 and 500 are the most reasonable
>values, but you shouldn't count on them.
I don't understand how you can interpret that paragraph to have such
a meaning. Section 7.2 requires exactly what I said. Here is paragraph 9:
"An expression of arithmetic or enumeration type can be converted to an
enumeration type explicitly. The value is UNCHANGED if it is in the range
of enumeration values of the enumeration type; otherwise the resulting
enumeration value is unspecified." [uppercase is mine]
The "range" of the enumeration is defined in paragraph 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. It is possible to define an enumeration that has values
not defined by any of its enumerators."
The "underlying type" is defined in paragraph 5:
"The underlying type of an enumeration is an integral type that can
represent all the enumerator values defined in the enumeration."
The min and max values of "spicyness" are 0 and 2000. The smallest
bit-field that can represent those values is 11 bits, if we assume
unsigned short or int as the underlying type. (The exact underlying
type doesn't matter for this discussion; the implementation can choose
any suitable underlying type, and I'm assuming it chooses a small one.)
A 11-bit unsigned field can represent all values in the range 0-2047,
and that is the guaranteed range of the enumeration. (An implementation
may allow a larger range, but is not required to.)
Any value in the range 0-2047 is therefore convertable to type
spicyness, and the value must remain unchanged.
Since 100 and 500 are in the range of the enumeration values, "mild"
and "hot" must have the values 100 and 500, respectively. They must
therefore compare equal to 100 and 500.
---
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html ]