Topic: Forward declaration of enum


Author: richard@ex-parrot.com ("Richard Smith")
Date: Wed, 12 Mar 2003 23:00:37 +0000 (UTC)
Raw View
"A Cappella Guy" <acappellaguy@hotmail.com> wrote:

> The second argument I don't understand as well, but has to do with a
> guarantee that all class pointers are the same size, but that enum
> pointers do not have to be.  This is deeper than my knowledge of how
> compilers work, but if a type's pointer size affects the declaration of
> a function that uses that type by value, and there is a good technical
> reason for making enum pointers be of flexible size, I'd like to hear
> the whole story.

Let me try to clarify.

On some architectures pointers to characters and pointers to ints are of
different sizes.  I.e.  sizeof(char*) != sizeof(int*).  This is sometimes
(usually?) because on the underlying architecture, machine words are easily
addressed (this is what the int* pointer is doing) whereas bytes are
addressed using a pointer to a word and an offset from that.  You could
imagine the two pointers being a bit like

  /* pseudocode */
  struct int* {
    int word;
  };

  struct char* {
    int word;
    int offset;
  };

When C++ sees an enum, it is allowed to choose any integral type (well,
nearly any -- it can only choose something larger than an int if it can't
fit in anything smaller) as its underlying type.  This means an
implementation *may* choose a char as the underlying type.  Whether a
compiler takes advantage of this flexibility is a QoI issue and will depend
on the compiler's intended use: an compiler for embedded platforms where
space is at a premium is much more likely to make this optimisation than a
compiler primarily targeted at 'desktop' platforms where better runtime
efficiency *might* result from making all enums the size of the underlying
machine word.

If the compiler only sees a declaration of an enum without a declaration, it
doesn't know how large the largest enumerator is, and so can't necessarily
tell what the underlying integral type is.  (A compiler that uses the same
underlying type of all enums, such as gcc with -fno-short-enums on ix86 does
not suffer from this problem.)  Because pointers to different integral types
are allowed to be of different sizes (and are in real world examples, such
as the one above), the compiler cannot know how large to make a pointer to a
forward declared enum.  The same applies to references since compilers
frequently implement references as pointers (at least regarding calling
convention).

Thus, the following code is not legal

  enum enum_type;
  void foo( enum_type const& e );
  void bar( enum_type const& e ) { foo(e); }

The corresponding case with a struct / class / union *does* work because the
Standard makes an explicit requirement for pointers to structs to have the
same size.  This means that on architectures where byte addresses are larger
than word addresses (for example) structs must be word aligned which results
in a potential waste of space in the case of very small structs.  In the
case of structs there is a very good reason to be able to forward declare
them, namely to handle cyclic references:

  struct B;
  struct A { B* b; };
  struct B { A* a; };

This construct was been present back in K&R C and has been retained in C90
and C++98.  For enums the possibility of cyclic references does not exist
and the importance of being able to optimise small enums is much more
important than for small structs -- many (most?) enums only a couple of
bytes, a typical struct is somewhat larger.  As a result the C and C++
Standards committees have both decided that the disadvantages outweigh the
advantages and have prohibited forward declaration of enums.

Note that none of this argument is not an argument against allowing forward
declaration of enums per se, merely an argument against allowing the code

  enum enum_type;
  void foo( enum_type const& e );
  void bar( enum_type const& e ) { foo(e); }

--
Richard Smith


---
[ 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                       ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 17 Mar 2003 21:29:56 +0000 (UTC)
Raw View
richard@ex-parrot.com ("Richard Smith") wrote (abridged):
> The corresponding case with a struct / class / union *does* work
> because the Standard makes an explicit requirement for pointers
> to structs to have the same size.  This means that on
> architectures where byte addresses are larger than word addresses
> (for example) structs must be word aligned which results in a
> potential waste of space in the case of very small structs.

Alternatively, the compiler could choose to make sizeof(struct *) ==
sizeof(char *). I imagine this is a rare case for structs because
pointers and references to them are quite common. However, it may be
a viable choice for enums.

Thus if we change C++ to allow incomplete enum types, and also require
pointers to them be complete types, then a platform with sizeof(char *)
!= sizeof(int *) would have two options:

(1) sizeof(enum *) == sizeof(char *)
(2) sizeof(enum) == sizeof(int)

Does anyone know of a real-world compiler which doesn't already adopt
one of these schemes? Ie that would have to change if the proposal
became standard?

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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                       ]





Author: zack@codesourcery.com (Zack Weinberg)
Date: Fri, 7 Mar 2003 00:24:13 +0000 (UTC)
Raw View
ron@sensor.com ("Ron Natalie") writes:

> "Zack Weinberg" <zack@codesourcery.com> wrote:
>> No, I still do not think there is a problem.  Even with -fshort-enums,
>> to be consistent with the platform calling convention, enumeration
>> values will be extended to register width when passed as formal
>> parameters or return values.
>
> Which platform are you assuming you have?

I claim this is a universal characteristic of ABIs.  Point me at a
single counterexample and I'll shut up (but you have to cite an actual
document).

zw

---
[ 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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Fri, 7 Mar 2003 18:22:06 +0000 (UTC)
Raw View
In article <878yvsz6ml.fsf@egil.codesourcery.com>, Zack Weinberg
<zack@codesourcery.com> writes
>No, I still do not think there is a problem.  Even with -fshort-enums,
>to be consistent with the platform calling convention, enumeration
>values will be extended to register width when passed as formal
>parameters or return values.

That is making assumptions about the architecture that I suspect are not
universally true.


--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: ron@sensor.com ("Ron Natalie")
Date: Fri, 7 Mar 2003 18:22:26 +0000 (UTC)
Raw View
"Zack Weinberg" <zack@codesourcery.com> wrote in message news:87wujcxhlx.fsf@egil.codesourcery.com...
> ron@sensor.com ("Ron Natalie") writes:
>
> > "Zack Weinberg" <zack@codesourcery.com> wrote:
> >> No, I still do not think there is a problem.  Even with -fshort-enums,
> >> to be consistent with the platform calling convention, enumeration
> >> values will be extended to register width when passed as formal
> >> parameters or return values.
> >
> > Which platform are you assuming you have?
>
> I claim this is a universal characteristic of ABIs.  Point me at a
> single counterexample and I'll shut up (but you have to cite an actual
> document).

Check your GCC source for the 1750a, mc68hc1, s390 (linux) cases
I believe.  Certainly it is not a universal characturistic.  C specifically
makes rules in the function declarations that allow for the non-promotion.
I got bit by that piece of undefined behavior on at least one platform
(probably an older HP).





---
[ 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                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 8 Mar 2003 00:57:44 +0000 (UTC)
Raw View
ron@sensor.com ("Ron Natalie") wrote
> You're only thinking of the size.   The thing is that dereferencing an enum
> pointer compiles directly into dereferencing the underlying integral type.
> If you force pointer compliance between all types, you incur computational
> overhead dereferencing these things.   Even on machines where pointers
> are all the same size, it is often the case that void*/char* to int*
> conversion (or vice versa) requires more than a simple copy.

Can you give an example of a platform where pointers all have the same
size, but different representations?

AFAIK, the only reason that pointers would have different representation,
is where the CPU has instructions that use non-byte addresses. But surely
if you need more bits for byte-address than quadword-address, the pointers
cannot be the same size either?

I'm certainly missing something. Please enlighten me.

---
[ 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                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 8 Mar 2003 00:57:56 +0000 (UTC)
Raw View
gdr@integrable-solutions.net (Gabriel Dos Reis) wrote
> Anyway, value extension may happen at the register level, not
> necessarily at the memory level. Given that one gets troubles with
> pointer arithmetic in case where the natural register width is that of
> an int and the enum has char as the underlying integer type and
> sizeof (char) != sizeof (int).

If a machine cannot address individual bytes, it certainly makes
sense for char pointers to be longer than the others -- in order to
address individual bytes packed into one word.

On such a machine, it would not make sense (IMHO) for char to be the
underlying type of an enum. The extra code needed to unpack the correct
byte and use it as an enum, would subsume any savings of data.

Do you know of any platform that proves me wrong? Because I'm anxious
to discuss QOI issues with that implementation.

---
[ 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                       ]





Author: ron@sensor.com ("Ron Natalie")
Date: Mon, 10 Mar 2003 18:21:47 +0000 (UTC)
Raw View
"Allan W" <allan_w@my-dejanews.com> wrote in message news:7f2735a5.0303071601.26670412@posting.google.com...

> Can you give an example of a platform where pointers all have the same
> size, but different representations?

Certainly.    The Denelcor HEP supercomputer has two pointer representations:
char pointers which work much as you suspect, and word pointers.   The low
order bits in the word pointers denote the operand and subword selection.
If you assign a char pointer to a subword pointer without conversion you are
going to be surprised.   As a matter of fact we found all sorts of hilarity when
porting the BSD UNIX source code over, because there were countless places
of conversion-by-union, where they would store a short* and retrieve a int* or
such and you were suddenly bizarrely using the wrong operand size on subsequent
accesses.

> AFAIK, the only reason that pointers would have different representation,
> is where the CPU has instructions that use non-byte addresses. But surely
> if you need more bits for byte-address than quadword-address, the pointers
> cannot be the same size either?
>
In the hep case, it just reuses those low three bits for a different meaning between
char and other pointers.   Another sort-of example is the Cray.   The Cray had 24
bit address registers and has only WORD addressing.   The Cray essentially had
two data sizes char (8 bits) and everythign else (64 bits)...believe me this made
certain things like porting the TIFF library fun, which assumes that there would be
some 16 bit data type.    The char offset into a word was encoded in the highorder
3 bits of the 64 bit "pointer."  However, the hardware never really looked at anything
other than the low 24 bits.   You would lose the extra bits if you manipulated a pointer
as a int*.   Char addressing was rather inefficient as it had to pack/unpack the words.

Believe me the above was quite common for word addressed machines.



---
[ 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                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Tue, 11 Mar 2003 18:51:48 +0000 (UTC)
Raw View
ron@sensor.com ("Ron Natalie") wrote
> "Allan W" <allan_w@my-dejanews.com> wrote
> > Can you give an example of a platform where pointers all have the same
> > size, but different representations?
>
> Certainly.    The Denelcor HEP supercomputer has two pointer
> representations: char pointers which work much as you suspect,
> and word pointers.   The low order bits in the word pointers
> denote the operand and subword selection.  If you assign a
> char pointer to a subword pointer without conversion you are
> going to be surprised.   As a matter of fact we found all
> sorts of hilarity when porting the BSD UNIX source code over,
> because there were countless places of conversion-by-union,
< where they would store a short* and retrieve a int* or
> such and you were suddenly bizarrely using the wrong operand
> size on subsequent accesses.

At least you could keep your sense of humor!

> > AFAIK, the only reason that pointers would have different
> > representation, is where the CPU has instructions that use
> > non-byte addresses. But surely if you need more bits for
> > byte-address than quadword-address, the pointers cannot be
> > the same size either?

> In the hep case, it just reuses those low three bits for a
> different meaning between char and other pointers.   Another
> sort-of example is the Cray.   The Cray had 24 bit address
> registers and has only WORD addressing.   The Cray essentially
> had two data sizes char (8 bits) and everythign else
> (64 bits)...believe me this made certain things like porting
> the TIFF library fun, which assumes that there would be
> some 16 bit data type.    The char offset into a word was
> encoded in the highorder 3 bits of the 64 bit "pointer."
> However, the hardware never really looked at anything other
> than the low 24 bits.   You would lose the extra bits if you
> manipulated a pointer as a int*.   Char addressing was rather
> inefficient as it had to pack/unpack the words.
>
> Believe me the above was quite common for word addressed machines.

I had tried to think about word-addressed machines before, but I
never considered the case where the word size was greater than the
address range. Living in the world of Intel, it was always quite
the reverse.

So *ALL* pointers have bits that aren't used, but some have more than
others... Thanks for the explanation!

---
[ 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                       ]





Author: zack@codesourcery.com (Zack Weinberg)
Date: Wed, 5 Mar 2003 07:44:33 +0000 (UTC)
Raw View
vladimir.shiryaevNOSPAM@NOSPAMsympatico.ca ("Vladimir Shiryaev") writes:

> enum foo;
> foo func();
>
> In this case it's
>
> some_int_type func();
>
> It's supposed to be efficient. E.g. on x86 an integral type may be
> returned in AL, AX, or EAX.  So how the calls to `foo' may be
> compiled if the compiler still does not know the `phisycal' interface?

To inject some facts, GCC has supported forward declaration of enums
for over a decade.  This does not cause problems of the form that you
describe, because calling conventions for C/C++ source code
universally specify that all enums are given the same width (usually
that of 'int') when they appear as formal parameters or return values
of functions.

Typically you will find this set out in the ABI specification for the
relevant architecture and operating system.

zw

---
[ 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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Wed, 5 Mar 2003 17:48:26 +0000 (UTC)
Raw View
In article <87r89mtg43.fsf@egil.codesourcery.com>, Zack Weinberg
<zack@codesourcery.com> writes
>vladimir.shiryaevNOSPAM@NOSPAMsympatico.ca ("Vladimir Shiryaev") writes:
>
>> enum foo;
>> foo func();
>>
>> In this case it's
>>
>> some_int_type func();
>>
>> It's supposed to be efficient. E.g. on x86 an integral type may be
>> returned in AL, AX, or EAX.  So how the calls to `foo' may be
>> compiled if the compiler still does not know the `phisycal' interface?
>
>To inject some facts, GCC has supported forward declaration of enums
>for over a decade.  This does not cause problems of the form that you
>describe, because calling conventions for C/C++ source code
>universally specify that all enums are given the same width (usually
>that of 'int') when they appear as formal parameters or return values
>of functions.
>
>Typically you will find this set out in the ABI specification for the
>relevant architecture and operating system.

And for C that is fine because C does not place any requirement to
support enums with enumerators that are larger than INT_MAX, but C++
does, so how do we handle cases where int is not large enough?  C++ also
allows, but does not require, the use of a char type if it would be
large enough.


--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: usenet_cpp@lehrerfamily.com (Joshua Lehrer)
Date: Wed, 5 Mar 2003 21:50:11 +0000 (UTC)
Raw View
philippe_mori@hotmail.com ("Philippe Mori") wrote in message news:<Khc9a.2044$KJ3.523131@news20.bellglobal.com>...
>
> The reason where forward declaration often becaume interesting
> is when trying to reduce compilation depedencies in real life
> project with minimal changes and new files (i.e. splitting files).

That's exactly my point.  I understand that you can't CALL a function
that uses a forward declared enum.  You also can't implement it.  But,
I'd like to get my enums that are used privately out of the class
header file.  I see no reason why this shouldn't be legal:

--- foo.h ---
enum result;
struct foo {
 //public interface
private:
 result impl_method();
};
--- foo.cxx ---
#include "foo.h"
enum result { eR1, eR2 };
result foo::impl_method() {
 return eR1;
}
--- consumer.cxx ---
#include "foo.h"
foo f;
--- done ---

the consumer now doesn't need to recompile each time we add an enum
value.  All the consumer needs to know is that "result" is a type
which can be returned from a function.  As the consumer never calls
the function, they don't need the full definition.

The implementation fully defines the enum, then implements the
function.

joshua lehrer
factset research systems
NYSE:FDS

---
[ 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                       ]





Author: acappellaguy@hotmail.com (A Cappella Guy)
Date: Wed, 5 Mar 2003 21:50:23 +0000 (UTC)
Raw View
In article <RAo1GIBibcZ+Ewrq@robinton.demon.co.uk>, Francis Glassborow
<francis.glassborow@ntlworld.com> wrote:

> In article <87r89mtg43.fsf@egil.codesourcery.com>, Zack Weinberg
> <zack@codesourcery.com> writes
> >vladimir.shiryaevNOSPAM@NOSPAMsympatico.ca ("Vladimir Shiryaev") writes:
> >To inject some facts, GCC has supported forward declaration of enums
> >for over a decade.  This does not cause problems of the form that you
> >describe, because calling conventions for C/C++ source code
> >universally specify that all enums are given the same width (usually
> >that of 'int') when they appear as formal parameters or return values
> >of functions.
>
> And for C that is fine because C does not place any requirement to
> support enums with enumerators that are larger than INT_MAX, but C++
> does, so how do we handle cases where int is not large enough?  C++ also
> allows, but does not require, the use of a char type if it would be
> large enough.

My guess is that gcc doesn't guarantee that all enum types are the same
size, but that all pointers to enum types are the same size, likely the
same size as all pointers to class instances.  Thus forward declaration
can be supported in those instances where forward declaration of
classes would be.

The feature is also supported in VC++, but I think MS goes a step
further and just says all enums are 32 bits, and if you try to assign a
higher number it fails.  It was only when I joined a company that had
me porting some of their old code to Mac that I found out that forward
declaration of enums wasn't actually part of the language, as it's not
supported in CodeWarrior.  It really does intuitively feel like it
should be.

 -- A Cappella Guy

---
[ 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                       ]





Author: llewelly.at@xmission.dot.com (LLeweLLyn)
Date: Wed, 5 Mar 2003 21:50:35 +0000 (UTC)
Raw View
zack@codesourcery.com (Zack Weinberg) writes:

> vladimir.shiryaevNOSPAM@NOSPAMsympatico.ca ("Vladimir Shiryaev") writes:
>
> > enum foo;
> > foo func();
> >
> > In this case it's
> >
> > some_int_type func();
> >
> > It's supposed to be efficient. E.g. on x86 an integral type may be
> > returned in AL, AX, or EAX.  So how the calls to `foo' may be
> > compiled if the compiler still does not know the `phisycal' interface?
>
> To inject some facts, GCC has supported forward declaration of enums
> for over a decade.

For C. Not for C++. For Vladimir's code, g++ 3.2.2 says:

   enum.cc:1: use of enum `foo' without previous declaration

   I believe gcc stopped supporting forward declaration of enums in
   C++ in the egcs days. Certainly 2.95 didn't allow it:

   http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC100

   says that for 2.95.3, 'This extension is not supported by GNU C++.'

> This does not cause problems of the form that you
> describe, because calling conventions for C/C++ source code
> universally specify that all enums are given the same width (usually
> that of 'int') when they appear as formal parameters or return values
> of functions.
>
> Typically you will find this set out in the ABI specification for the
> relevant architecture and operating system.
[snip]

---
[ 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                       ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Wed, 5 Mar 2003 21:50:41 +0000 (UTC)
Raw View
gdr@integrable-solutions.net (Gabriel Dos Reis) wrote (abridged):
> | Yet no known implementation that has sizeof(char *) !=
> | sizeof(int *) chooses to use have sizeof(enum) == sizeof(char),
> | so the issue doesn't arise.
>
> That is untrue: some implementations uses "unsigned char" or "char"
> as the underlying integer types of enums (GCC at least when invoked
> with suitable switches).

That doesn't contradict what I wrote unless such implementations also
have sizeof(char *) != sizeof(int *). There are two conditions here:

(1) sizeof(char *) != sizeof(int *)
(2) sizeof(enum) == sizeof(char)

Can you name an implementation which satisfies both conditions?

It's a genuine question. Implementations which satisfy the first
condition are quite rare so I may have missed something. As I
understand it, they tend to be "unfriendly" to chars. For example,
char operations will tend to be slower than the corresponding int
ones, and of course any space saving from the smaller enum may be
partially offset by the larger pointer-to-enum.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Wed, 5 Mar 2003 22:22:30 +0000 (UTC)
Raw View
In article <050320031043274517%acappellaguy@hotmail.com>, A Cappella Guy
<acappellaguy@hotmail.com> writes
>The feature is also supported in VC++, but I think MS goes a step
>further and just says all enums are 32 bits, and if you try to assign a
>higher number it fails.  It was only when I joined a company that had
>me porting some of their old code to Mac that I found out that forward
>declaration of enums wasn't actually part of the language, as it's not
>supported in CodeWarrior.  It really does intuitively feel like it
>should be.


Then, IMHO, it is time to re-educate your intuition. Focus on pass and
return by value because we simply do not use pointers and references to
enums. Now the value of forward declarations seems far less useful.

--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: zack@codesourcery.com (Zack Weinberg)
Date: Wed, 5 Mar 2003 22:56:48 +0000 (UTC)
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) writes:

>>To inject some facts, GCC has supported forward declaration of enums
>>for over a decade.
...
> And for C that is fine because C does not place any requirement to
> support enums with enumerators that are larger than INT_MAX, but C++
> does, so how do we handle cases where int is not large enough?  C++
> also allows, but does not require, the use of a char type if it would
> be large enough.

As I said, this is all set out in the calling convention
specification, which is part of the platform ABI.  I think you will
find, if you look at such documents, that there is no actual problem.

(GNU C++ doesn't support this extension only because GNU C++ is - by
design - a pickier compiler than GNU C.)

zw

---
[ 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                       ]





Author: pavel@despammed.com ("Pavel Kuznetsov")
Date: Thu, 6 Mar 2003 00:32:09 +0000 (UTC)
Raw View
Vladimir Shiryaev (vladimir.shiryaevNOSPAM@NOSPAMsympatico.ca) wrote:

VS> enum foo;
VS> foo func();

VS> In this case it's

VS> some_int_type func();

VS> It's supposed to be efficient. E.g. on x86 an integral type may be
VS> returned in AL, AX, or EAX.  So how the calls to `foo' may be
VS> compiled if the compiler still does not know the `phisycal'
VS> interface?

They can't. But the point is that though it is not possible to call
that function, still it can be useful to be able to declare it without
defining enum involved in the function's declaration.

Take for example private member function of the class:

  class C
  {
    ...

  private:
    enum foo;
    foo func();
  };

This `foo' enum is an implementation detail of this class and there's
no point in insisting on its definition in the class body if the `func'
is not called from inline member functions defined in the same header
as the `C' class itself.

--
Pavel

---
[ 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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 6 Mar 2003 00:37:28 +0000 (UTC)
Raw View
In article <memo.20030305205841.37217E@brangdon.madasafish.com>, Dave
Harris <brangdon@cix.co.uk> writes
>It's a genuine question. Implementations which satisfy the first
>condition are quite rare so I may have missed something. As I
>understand it, they tend to be "unfriendly" to chars. For example,
>char operations will tend to be slower than the corresponding int
>ones, and of course any space saving from the smaller enum may be
>partially offset by the larger pointer-to-enum.

However, using pointers to enum or references to enum is uncommon, so
saving space for enum values is more significant.

--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 6 Mar 2003 05:10:44 +0000 (UTC)
Raw View
In article <31c49f0d.0303050833.7ab06748@posting.google.com>, Joshua
Lehrer <usenet_cpp@lehrerfamily.com> writes
>That's exactly my point.  I understand that you can't CALL a function
>that uses a forward declared enum.  You also can't implement it.  But,
>I'd like to get my enums that are used privately out of the class
>header file.  I see no reason why this shouldn't be legal:
>
>--- foo.h ---
>enum result;
>struct foo {
> //public interface
>private:
> result impl_method();
>};
>--- foo.cxx ---
>#include "foo.h"
>enum result { eR1, eR2 };
>result foo::impl_method() {
> return eR1;
>}
>--- consumer.cxx ---
>#include "foo.h"
>foo f;
>--- done ---
>
>the consumer now doesn't need to recompile each time we add an enum
>value.  All the consumer needs to know is that "result" is a type
>which can be returned from a function.  As the consumer never calls
>the function, they don't need the full definition.
>
>The implementation fully defines the enum, then implements the
>function.

So move the enum AND the function to an unnamed namespace in the
implementation file.

Or stop using enums. Consider using a struct with a series of static
const ints to provide the equivalent of enumeration values, and so on
There arer plenty of alternatives when you 'need' them.


--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: usenet_cpp@lehrerfamily.com (Joshua Lehrer)
Date: Thu, 6 Mar 2003 06:13:48 +0000 (UTC)
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote in message news:<VblEQ7BUTnZ+Ewaa@robinton.demon.co.uk>...
> Then, IMHO, it is time to re-educate your intuition. Focus on pass and
> return by value because we simply do not use pointers and references to
> enums. Now the value of forward declarations seems far less useful.

Again, I disagree.  I'd like to forward declare an enum return value,
and a function.  If the consumer never calls the function, they
shouldn't need to see the full definition of the enum:

enum returnTypeA;
returnTypeA funcA();

bool funcB();

A consumer should be able to include this file, and call funcB()
without ever calling funcA() or seeing the full definition of
returnTypeA.

joshua lehrer
factset research systems
NYSE:FDS

---
[ 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                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 6 Mar 2003 10:49:39 +0000 (UTC)
Raw View
zack@codesourcery.com (Zack Weinberg) writes:

| francis.glassborow@ntlworld.com (Francis Glassborow) writes:
|
| >>To inject some facts, GCC has supported forward declaration of enums
| >>for over a decade.
| ...
| > And for C that is fine because C does not place any requirement to
| > support enums with enumerators that are larger than INT_MAX, but C++
| > does, so how do we handle cases where int is not large enough?  C++
| > also allows, but does not require, the use of a char type if it would
| > be large enough.
|
| As I said, this is all set out in the calling convention
| specification, which is part of the platform ABI.  I think you will
| find, if you look at such documents, that there is no actual problem.

Some notes:  The terminilogy you're using here is extremely confusing.
GCC means "GNU Compiler Collection", not "GNU C Compiler".  Therefore,
when you come to mention GCC in a C++ group, some people understand
the C++ part of the GNU Compiler Collection while, in fact, you were
actually referring to the C part of GCC.

As of the enum forward declaration issue, you're forgettiing
-fshort-enums which puts GCC/g++ is a distinctive position compared to
GCC/gcc: In GNU C++, enums cna be shorter than in GNU C, and in thoses
cases there are problems.

Now, if your point is that on a system where the ABI requires enums
to use "int" as the underlying integer type there is no problem, then
that is an obious fact which nobody is disputing.
But, in effect, no single size fits everybody.

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 6 Mar 2003 16:34:19 +0000 (UTC)
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) writes:

[...]

|                                                                 C++
| also allows, but does not require, the use of a char type if it would
| be large enough.

And in reality, GCC does use char (or signed variant) to implement
enums where appropriate, if invoked with -fshort-enums.

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 6 Mar 2003 16:35:32 +0000 (UTC)
Raw View
In article <873cm1igyt.fsf@egil.codesourcery.com>, Zack Weinberg
<zack@codesourcery.com> writes
>francis.glassborow@ntlworld.com (Francis Glassborow) writes:
>
>>>To inject some facts, GCC has supported forward declaration of enums
>>>for over a decade.
>...
>> And for C that is fine because C does not place any requirement to
>> support enums with enumerators that are larger than INT_MAX, but C++
>> does, so how do we handle cases where int is not large enough?  C++
>> also allows, but does not require, the use of a char type if it would
>> be large enough.
>
>As I said, this is all set out in the calling convention
>specification, which is part of the platform ABI.  I think you will
>find, if you look at such documents, that there is no actual problem.
>
>(GNU C++ doesn't support this extension only because GNU C++ is - by
>design - a pickier compiler than GNU C.)

Pickier or just that the requirements of C++ simply make it impractical?
I think that the very fact that GNU C++ does not support forward
declaring and enum whilst GNU C does should tell you something. Those
compilers have an extra (over and above the Standard ones)
incompatibility because of that extension to GNU C, one which I am sure
GNU C++ would have avoided if it had been cost free.


--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 6 Mar 2003 17:19:53 +0000 (UTC)
Raw View
Joshua Lehrer wrote:
> they shouldn't need to see the full definition

I know that this is almost an obsession with some people,
but incomplete types are there to support mutually recursive
structs. This has allowed other uses to evolve, but that
doesn't mean that things which don't need the mutual recursion
ability should be modified to support incompleteness.

---
[ 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                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 6 Mar 2003 18:33:28 +0000 (UTC)
Raw View
acappellaguy@hotmail.com (A Cappella Guy) writes:

| My guess is that gcc doesn't guarantee that all enum types are the same
| size, but that all pointers to enum types are the same size, likely the
| same size as all pointers to class instances.

I didn't see such guarantee written anywhere.

And in effect, that can't be on a target where:

   * int* and char* have completely different objet representation
     requirements

   * -fshort-enums is used as part of the compiler invokation, and
      where char is used as the underlying integral type.

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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                       ]





Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Thu, 6 Mar 2003 18:33:40 +0000 (UTC)
Raw View
> >That's exactly my point.  I understand that you can't CALL a function
> >that uses a forward declared enum.  You also can't implement it.  But,
> >I'd like to get my enums that are used privately out of the class
> >header file.  I see no reason why this shouldn't be legal:
> >
> >--- foo.h ---
> >enum result;
> >struct foo {
> > //public interface
> >private:
> > result impl_method();
> >};
> >--- foo.cxx ---
> >#include "foo.h"
> >enum result { eR1, eR2 };
> >result foo::impl_method() {
> > return eR1;
> >}
> >--- consumer.cxx ---
> >#include "foo.h"
> >foo f;
> >--- done ---
> >
> >the consumer now doesn't need to recompile each time we add an enum
> >value.  All the consumer needs to know is that "result" is a type
> >which can be returned from a function.  As the consumer never calls
> >the function, they don't need the full definition.
> >
> >The implementation fully defines the enum, then implements the
> >function.
>
> So move the enum AND the function to an unnamed namespace in the
> implementation file.
>
> Or stop using enums. Consider using a struct with a series of static
> const ints to provide the equivalent of enumeration values, and so on
> There arer plenty of alternatives when you 'need' them.
>
>

Using an int instead of an enum is often not a good alternative
because enum provide some form of type checking. And that
can be a benefit if a function have many parameters and/or
overload since it help ensure that we call the appropriate
function with the appropriate arguments at the proper position...

---
[ 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                       ]





Author: llewelly.at@xmission.dot.com (LLeweLLyn)
Date: Thu, 6 Mar 2003 19:47:13 +0000 (UTC)
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) writes:
[snip]
> And that is the vital point, we cannot allow forward declaration of
> enums by analogy with forward declaring classes without imposing a cost
> that few want to pay

Few would have to pay it. Implementations where the size of void*
    differs from the size of struct foo* are rare. In any case the
    cost of enun bar* on such implementations would be no worse than
    the cost of void* on the same implementations, and there would be
    an alternative: force the sizeof any enum to be a multiple of
    sizeof(int), allowing enum bar* to have the same width and
    representation as int*. How many platforms are there where niether
    would be a teneable alternative? Do these platforms support C,
    which nearly requires int* and enum foo* to have the same
    width and representation?

> (fixing the size and layout of a pointer to enum).
> The marginal advantage of allowing:
>
> enum E;
>
> E foo();
>
> seems insufficient for the complexity of a forward declaration rule for
> enums that is significantly different to that for a class type.

Now I do think that if forward declaration of enums is to be allowed,
    it should be as similar as feasible to the rules for forward
    declaration of classes. I think Joshua showed the advantages of
    forward declaration of enums. I think they are almost as small as
    the cost of adding the extension to the standard. :-)

---
[ 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                       ]





Author: acappellaguy@hotmail.com (A Cappella Guy)
Date: Thu, 6 Mar 2003 20:05:03 +0000 (UTC)
Raw View
In article <VblEQ7BUTnZ+Ewaa@robinton.demon.co.uk>, Francis Glassborow
<francis.glassborow@ntlworld.com> wrote:

> In article <050320031043274517%acappellaguy@hotmail.com>, A Cappella Guy
> <acappellaguy@hotmail.com> writes
> >The feature is also supported in VC++, but I think MS goes a step
> >further and just says all enums are 32 bits, and if you try to assign a
> >higher number it fails.  It was only when I joined a company that had
> >me porting some of their old code to Mac that I found out that forward
> >declaration of enums wasn't actually part of the language, as it's not
> >supported in CodeWarrior.  It really does intuitively feel like it
> >should be.
>
> Then, IMHO, it is time to re-educate your intuition. Focus on pass and
> return by value because we simply do not use pointers and references to
> enums. Now the value of forward declarations seems far less useful.

Ok, then using all pass-by-value, the following works:

class Enum;

class UsesEnum {
public:
   bool IsSecond(Enum e) const;
   Enum GetSecond() const;
};

class Enum {
public:
   enum E {
      kFirst,
      kSecond,
      kThird
   };
   Enum(const E& e) : m_Value(e) {}
   operator E() const { return m_Value; }
private:
   E m_Value;
};

bool UsesEnum::IsSecond(Enum e) const { return e == Enum::kSecond; }
Enum UsesEnum::GetSecond() const { return Enum::kSecond; }

int main() {
   UsesEnum ue;
   Enum second = ue.GetSecond();
   bool bSecond = ue.IsSecond(second);
}

The code that uses the rough enum-approximating class has no idea of
its size or representation, just that it exists.  And that's all it has
to know at the point.  By the time UsesEnum does any implementation
based on Enum, it would have included the class definition _in the cpp
file_.

If this can be done for a class that contains an enum, it should be
possible for a bare enum.

I've heard two explanations that make some sense to me.  The first,
that the purpose of forward declarations is entirely to avoid cyclic
dependency problems, doesn't ring true.  Languages evolve, as the
current state of the art in generic programming will attest, and if
people want to forward declare enums to avoid unnecessary compile-time
dependencies, that shouldn't remain illegal just because
forward-declare of classes wasn't meant for that purpose either.

The second argument I don't understand as well, but has to do with a
guarantee that all class pointers are the same size, but that enum
pointers do not have to be.  This is deeper than my knowledge of how
compilers work, but if a type's pointer size affects the declaration of
a function that uses that type by value, and there is a good technical
reason for making enum pointers be of flexible size, I'd like to hear
the whole story.

 -- A Cappella Guy

---
[ 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                       ]





Author: usenet_cpp@lehrerfamily.com (Joshua Lehrer)
Date: Thu, 6 Mar 2003 21:36:21 +0000 (UTC)
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote in message news:<rrFLcvCXYnZ+Ew$a@robinton.demon.co.uk>...
>
> So move the enum AND the function to an unnamed namespace in the
> implementation file.
>
> Or stop using enums. Consider using a struct with a series of static
> const ints to provide the equivalent of enumeration values, and so on
> There arer plenty of alternatives when you 'need' them.

The method must be a member, it needs access to private data and the
ability to call private methods.

And using a struct instead of an enum is an annoying hack to get
around an issue with enums and opens up its own can of worms.

Why can't we allow forward declaration of enums, accepting the fact
that we don't know the size of the enum (just like a forward declared
class) AND we don't know the size of a pointer to the enum.  As you
have said, pointers to enums are rarely used anyway.

This would be allowed:

enum e;
struct s;
e foo(e); //proposed enhancement
s foo(s); //works now

this would not:

struct s;
enum e;
struct foo {
 s obj; //incomplete type
 e val; //incomplete type
};

and this would partially work:

struct s;
enum e;
struct foo {
 s* pobj; //works now
 e* pval; //incomplete type, error.
};

joshua lehrer
factset research systems
NYSE:FDS

---
[ 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                       ]





Author: zack@codesourcery.com (Zack Weinberg)
Date: Thu, 6 Mar 2003 21:36:49 +0000 (UTC)
Raw View
gdr@integrable-solutions.net (Gabriel Dos Reis) writes:

> Some notes: The terminilogy you're using here is extremely
> confusing.  GCC means "GNU Compiler Collection", not "GNU C
> Compiler".  Therefore, when you come to mention GCC in a C++ group,
> some people understand the C++ part of the GNU Compiler Collection
> while, in fact, you were actually referring to the C part of GCC.

I used that terminology because I remembered (incorrectly) that
forward declaration of enums was supported in both GNU C and GNU C++.
I apologize for the confusion.

> As of the enum forward declaration issue, you're forgettiing
> -fshort-enums which puts GCC/g++ is a distinctive position compared
> to GCC/gcc: In GNU C++, enums cna be shorter than in GNU C, and in
> thoses cases there are problems.

No, I still do not think there is a problem.  Even with -fshort-enums,
to be consistent with the platform calling convention, enumeration
values will be extended to register width when passed as formal
parameters or return values.

zw

---
[ 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                       ]





Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 6 Mar 2003 21:37:28 +0000 (UTC)
Raw View
"LLeweLLyn" <llewelly.at@xmission.dot.com> wrote in message news:m1smu0ub44.fsf@localhost.localdomain...
> francis.glassborow@ntlworld.com (Francis Glassborow) writes:
> [snip]
> > And that is the vital point, we cannot allow forward declaration of
> > enums by analogy with forward declaring classes without imposing a cost
> > that few want to pay
>
> Few would have to pay it. Implementations where the size of void*
>     differs from the size of struct foo* are rare. In any case the
>     cost of enun bar* on such implementations would be no worse than
>     the cost of void* on the same implementations,

You're only thinking of the size.   The thing is that dereferencing an enum
pointer compiles directly into dereferencing the underlying integral type.
If you force pointer compliance between all types, you incur computational
overhead dereferencing these things.   Even on machines where pointers
are all the same size, it is often the case that void*/char* to int* conversion
(or vice versa) requires more than a simple copy.



---
[ 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                       ]





Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 6 Mar 2003 21:52:34 +0000 (UTC)
Raw View
"Zack Weinberg" <zack@codesourcery.com> wrote in message news:878yvsz6ml.fsf@egil.codesourcery.com...
> gdr@integrable-solutions.net (Gabriel Dos Reis) writes:

> No, I still do not think there is a problem.  Even with -fshort-enums,
> to be consistent with the platform calling convention, enumeration
> values will be extended to register width when passed as formal
> parameters or return values.

Which platform are you assuming you have?



---
[ 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                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 6 Mar 2003 22:25:20 +0000 (UTC)
Raw View
zack@codesourcery.com (Zack Weinberg) writes:

[...]

| > As of the enum forward declaration issue, you're forgettiing
| > -fshort-enums which puts GCC/g++ is a distinctive position compared
| > to GCC/gcc: In GNU C++, enums cna be shorter than in GNU C, and in
| > thoses cases there are problems.
|
| No, I still do not think there is a problem.  Even with -fshort-enums,
| to be consistent with the platform calling convention, enumeration
| values will be extended to register width when passed as formal
| parameters or return values.

That's essentially saying that the compiler ought to make a char as wide
as registers.  That might be true, but only a very specific platform,
not that of the vaste majority.

Anyway, value extension may happen at the register level, not
necessarily at the memory level. Given that one gets troubles with
pointer arithmetic in case where the natural register width is that of
an int and the enum has char as the underlying integer type and
sizeof (char) != sizeof (int).

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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                       ]





Author: usenet_cpp@lehrerfamily.com (Joshua Lehrer)
Date: Fri, 28 Feb 2003 21:39:09 +0000 (UTC)
Raw View
ron@sensor.com ("Ron Natalie") wrote in message news:<HJ97a.2680$ty3.2176@fe03.atl2.webusenet.com>...
> The standard allows the implementation to size the underlying enum type
> based (based on the range of enumerator values).   Unless you
> know what the enumerators are, you can't tell what size the enum is.

so?  different classes have different sizes, and you can forward
declare them.  The point isn't that enums can have different sizes,
but that pointers to enums can have different sizes.  The standard
requires all pointers to classes/structs to be of one size, it makes
no such requirement on pointers to enums.

joshua lehrer
factset research systems
NYSE:FDS

---
[ 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                       ]





Author: ron@sensor.com ("Ron Natalie")
Date: Fri, 28 Feb 2003 23:09:32 +0000 (UTC)
Raw View
"Joshua Lehrer" <usenet_cpp@lehrerfamily.com> wrote in message news:31c49f0d.0302281121.7e5def90@posting.google.com...
> ron@sensor.com ("Ron Natalie") wrote in message news:<HJ97a.2680$ty3.2176@fe03.atl2.webusenet.com>...
> > The standard allows the implementation to size the underlying enum type
> > based (based on the range of enumerator values).   Unless you
> > know what the enumerators are, you can't tell what size the enum is.
>
> so?  different classes have different sizes, and you can forward
> declare them.

Yes, but you can't make instances of them.   Pretty much all you can
do is create pointers of the incomplete types.  You asked about a return
value of enum, not a return value of pointer to enum.



---
[ 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                       ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 3 Mar 2003 03:38:31 +0000 (UTC)
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote (abridged):
> We have been round this loop many times.

True. But I don't think your reply is a fair summary of the issues.


> 1) Forward declaration only allows return by pointer or reference.

Not true. It also allows declaration of functions that pass or return by
value. Since:

    class C;
    C func( C c ); // Declaration, not call or definition.

is permitted, why not:
    enum E;
    E func( E e );  // Declaration, not call or definition.

? This in itself would be useful, even though such functions cannot be
called without completing the type. No references or pointers involved, so
the following issue does not effect this.


> 2) For efficiency reasons enums can be of different sizes with
> different underlying integral types.
> 3) For efficiency reasons pointers to types of different sizes are not
> only allowed to be different (in size and layout) but are actually
> different on existing architectures.

Yet no known implementation that has sizeof(char *) != sizeof(int *)
chooses to use have sizeof(enum) == sizeof(char), so the issue doesn't
arise. And if such a machine did exist, it could use sizeof(enum *) ==
sizeof(char *).


> The answer is that there is very little apparent gain at a cost that
> some do not wish to pay.

I think the real reason is "historical". The authors of the standard(s)
either did not think of it, or did not think it was worth spending time
on. They overlooked the significant benefit of partial enums for
dependency management.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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                       ]





Author: usenet_cpp@lehrerfamily.com (Joshua Lehrer)
Date: Mon, 3 Mar 2003 03:39:27 +0000 (UTC)
Raw View
ron@sensor.com ("Ron Natalie") wrote in message news:<3%Q7a.1936$d9.1609@fe09.atl2.webusenet.com>...
> "Joshua Lehrer" <usenet_cpp@lehrerfamily.com> wrote in message news:31c49f0d.0302281121.7e5def90@posting.google.com...
> > ron@sensor.com ("Ron Natalie") wrote in message news:<HJ97a.2680$ty3.2176@fe03.atl2.webusenet.com>...
> > > The standard allows the implementation to size the underlying enum type
> > > based (based on the range of enumerator values).   Unless you
> > > know what the enumerators are, you can't tell what size the enum is.
> >
> > so?  different classes have different sizes, and you can forward
> > declare them.
>
> Yes, but you can't make instances of them.   Pretty much all you can
> do is create pointers of the incomplete types.  You asked about a return
> value of enum, not a return value of pointer to enum.
>

This is legal:

struct foo;
foo func();


This is not:

enum foo;
foo func();


why not?

joshua lehrer
factset research systems
NYSE:FDS

---
[ 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                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Mon, 3 Mar 2003 05:54:35 +0000 (UTC)
Raw View
brangdon@cix.co.uk (Dave Harris) writes:

[...]

| > 2) For efficiency reasons enums can be of different sizes with
| > different underlying integral types.
| > 3) For efficiency reasons pointers to types of different sizes are not
| > only allowed to be different (in size and layout) but are actually
| > different on existing architectures.
|
| Yet no known implementation that has sizeof(char *) != sizeof(int *)
| chooses to use have sizeof(enum) == sizeof(char), so the issue doesn't
| arise.

That is untrue: some implementations uses "unsigned char" or "char" as
the underlying integer types of enums (GCC at least when invoked with
suitable switches).

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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                       ]





Author: ron@sensor.com ("Ron Natalie")
Date: Mon, 3 Mar 2003 18:52:35 +0000 (UTC)
Raw View
"Joshua Lehrer" <usenet_cpp@lehrerfamily.com> wrote in message news:31c49f0d.0303021509.30801108@posting.google.com...

> This is legal:
>
> struct foo;
> foo func();

No it is NOT.
\


---
[ 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                       ]





Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Tue, 4 Mar 2003 04:00:37 +0000 (UTC)
Raw View
> > The standard allows the implementation to size the underlying enum type
> > based (based on the range of enumerator values).   Unless you
> > know what the enumerators are, you can't tell what size the enum is.
>
> so?  different classes have different sizes, and you can forward
> declare them.  The point isn't that enums can have different sizes,
> but that pointers to enums can have different sizes.  The standard
> requires all pointers to classes/structs to be of one size, it makes
> no such requirement on pointers to enums.
>

I don't think that these reasons are sufficient oto not allows
forward declaration on enum. It should be possible weither
enum are of fixed sized or not and weither their pointer are
of fixed size or not.

Any uses that a compiler could compile without more
informations should compile. This include declaring
functions that have enum (or a pointer to an emun) as
a parameter as well as the return value.

To call that function, the definition would be required
if it is needed for that compiler (and it may be the same
think for a data member - value and/or pointer).

That way, the definition will be required when a
compiler needs it on a platform. It would never be
required for function declaration and it would be
up to the implementation for the others cases where
it is specific to a platform (ideally a platform that
is less restrictive would allows to have an optional
portability warning).

> joshua lehrer
> factset research systems
> NYSE:FDS
>


---
[ 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                       ]





Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Tue, 4 Mar 2003 04:00:56 +0000 (UTC)
Raw View
>
> > This is legal:
> >
> > struct foo;
> > foo func();
>
> No it is NOT.
> \
>
>

I think it is legal. At least some compiler accepts it...

It should compile if func is not called or if func is
called but the complete definition of foo appears
somewhere else before the call to foo.

---
[ 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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Tue, 4 Mar 2003 16:46:29 +0000 (UTC)
Raw View
In article <tsT8a.1187$KJ3.334678@news20.bellglobal.com>, Philippe Mori
<philippe_mori@hotmail.com> writes
>Any uses that a compiler could compile without more
>informations should compile. This include declaring
>functions that have enum (or a pointer to an emun) as
>a parameter as well as the return value.

OK, now tell me how a compiler is supposed to compile the following:

enum E;

void * fooE * e){
        return e;
}

Note that there is no problem with:

class C
void * foo (C * c){
        return c;
}

And that is the vital point, we cannot allow forward declaration of
enums by analogy with forward declaring classes without imposing a cost
that few want to pay (fixing the size and layout of a pointer to enum).
The marginal advantage of allowing:

enum E;

E foo();

seems insufficient for the complexity of a forward declaration rule for
enums that is significantly different to that for a class type.


--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: eldiener@earthlink.net ("Edward Diener")
Date: Wed, 5 Mar 2003 00:22:09 +0000 (UTC)
Raw View
Francis Glassborow wrote:
> In article <tsT8a.1187$KJ3.334678@news20.bellglobal.com>, Philippe
> Mori <philippe_mori@hotmail.com> writes
>> Any uses that a compiler could compile without more
>> informations should compile. This include declaring
>> functions that have enum (or a pointer to an emun) as
>> a parameter as well as the return value.
>
> OK, now tell me how a compiler is supposed to compile the following:
>
> enum E;
>
> void * fooE * e){
>         return e;
> }
>
> Note that there is no problem with:
>
> class C
> void * foo (C * c){
>         return c;
> }
>
> And that is the vital point, we cannot allow forward declaration of
> enums by analogy with forward declaring classes without imposing a
> cost that few want to pay (fixing the size and layout of a pointer to
> enum).

Nonetheless it does seem strange that the size and layout of a pointer to
different enums is specified as not necessarily being the same while the
size and layout of a pointer to different classes is specified as always
being the same. Or have I missed something here ?

---
[ 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                       ]





Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Wed, 5 Mar 2003 02:25:06 +0000 (UTC)
Raw View
>
> OK, now tell me how a compiler is supposed to compile the following:
>
> enum E;
>
> void * foo(E * e){
>         return e;
> }
>

I think that most compiler will have same pointer size and
representation for all pointers (classes, enum, char, void,...)
so on most compiler and platform the above code could
compile without problem.

>
> And that is the vital point, we cannot allow forward declaration of
> enums by analogy with forward declaring classes without imposing a cost
> that few want to pay (fixing the size and layout of a pointer to enum).
> The marginal advantage of allowing:
>
> enum E;
>
> E foo();
>
> seems insufficient for the complexity of a forward declaration rule for
> enums that is significantly different to that for a class type.
>
>

As someone point it (I think it was in this group), this allows private
enumerations that is used by private functions and make the definition
only in the implementation file. Thus it allows to avoid compile time
depedencies on the enumerated values and it does not require a less
safe alternative as using int in the interface...

So IMHO, forward declaration could be usable and usefull on most
system... if the information is optional. But I think that in most case
it is preferable to have the enumeration included since it is
lightweight anyway.

The reason where forward declaration often becaume interesting
is when trying to reduce compilation depedencies in real life
project with minimal changes and new files (i.e. splitting files).



---
[ 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                       ]





Author: vladimir.shiryaevNOSPAM@NOSPAMsympatico.ca ("Vladimir Shiryaev")
Date: Wed, 5 Mar 2003 07:09:53 +0000 (UTC)
Raw View
> This is legal:
>
> struct foo;
> foo func();
>
 > This is not:
>
> enum foo;
> foo func();
>
> why not?

1)

struct foo;
foo func();

`func' in this case is most likely compiled as if it was
declared like this:

void func(struct foo* result_location);

Calls to `foo' may be compiled even if the exact layout
of  `struct foo' is still unknown.

2)

enum foo;
foo func();

In this case it's

some_int_type func();

It's supposed to be efficient. E.g. on x86 an integral type may be
returned in AL, AX, or EAX.  So how the calls to `foo' may be
compiled if the compiler still does not know the `phisycal' interface?




---
[ 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                       ]





Author: acappellaguy@hotmail.com (A Cappella Guy)
Date: Wed, 26 Feb 2003 19:53:05 +0000 (UTC)
Raw View
Is there any reason why this would not be allowed?  Seems a shame to
have to include an entire header just because a function returns an
enum it defines.  Would there be any complications with adding

enum Foo;

....as a forward declaration to the standard?  Maybe enums aren't
guaranteed to be all the same size, and their only common use is
pass-by-value, so there would be no practical use for the declaration?
That's my best guess at the moment.

VC++ supports this as a non-standard extension and I guess always uses
int for enums, CodeWarrior does not, and chooses the sizes at
compile-time based on defined values (subject to #pragma enumsalwaysint
and longlong_enums).

 -- A Cappella Guy

---
[ 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                       ]





Author: rogero@howzatt.demon.co.uk ("Roger Orr")
Date: Wed, 26 Feb 2003 23:38:00 +0000 (UTC)
Raw View
"A Cappella Guy" <acappellaguy@hotmail.com> wrote in message
news:260220031120230732%acappellaguy@hotmail.com...
> Is there any reason why this would not be allowed?  Seems a shame to
> have to include an entire header just because a function returns an
> enum it defines.  Would there be any complications with adding
>
> enum Foo;
>
> ....as a forward declaration to the standard?  Maybe enums aren't
> guaranteed to be all the same size, and their only common use is
> pass-by-value, so there would be no practical use for the declaration?
> That's my best guess at the moment.

Yes, that is the right guess :-)

Since enums can be of different sizes there is as you point out little value
in forward declaring them.

Roger Orr
--
MVP in C++ at www.brainbench.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                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Wed, 26 Feb 2003 23:38:03 +0000 (UTC)
Raw View
In article <260220031120230732%acappellaguy@hotmail.com>, A Cappella Guy
<acappellaguy@hotmail.com> writes
>Is there any reason why this would not be allowed?  Seems a shame to
>have to include an entire header just because a function returns an
>enum it defines.  Would there be any complications with adding
>
>enum Foo;


We have been round this loop many times.

1) Forward declaration only allows return by pointer or reference.
2) For efficiency reasons enums can be of different sizes with different
underlying integral types.
3) For efficiency reasons pointers to types of different sizes are not
only allowed to be different (in size and layout) but are actually
different on existing architectures.

The answer is that there is very little apparent gain at a cost that
some do not wish to pay.

--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ 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                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 27 Feb 2003 05:16:29 +0000 (UTC)
Raw View
A Cappella Guy wrote:
> Is there any reason why this would not be allowed?

There's no reason for it. You need to be able to
forward declare structures so that you can have
circular references (A contains B*, B contains A*)
but this is not needed for enums.

---
[ 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                       ]





Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 27 Feb 2003 05:16:34 +0000 (UTC)
Raw View
"A Cappella Guy" <acappellaguy@hotmail.com> wrote in message news:260220031120230732%acappellaguy@hotmail.com...
> Is there any reason why this would not be allowed?  Seems a shame to
> have to include an entire header just because a function returns an
> enum it defines.  Would there be any complications with adding
>
> enum Foo;
>
The standard allows the implementation to size the underlying enum type
based (based on the range of enumerator values).   Unless you
know what the enumerators are, you can't tell what size the enum is.



---
[ 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                       ]





Author: richard@ex-parrot.com ("Richard Smith")
Date: Thu, 27 Feb 2003 16:42:23 +0000 (UTC)
Raw View
A Cappella Guy asks:

> >Is there any reason why this would not be allowed?  Seems a shame to
> >have to include an entire header just because a function returns an
> >enum it defines.  Would there be any complications with adding
> >
> >enum Foo;

Francis Glassborow replied:

> We have been round this loop many times.

[snip details]

> The answer is that there is very little apparent gain at a cost that
> some do not wish to pay.

But it does allow functions to be declared that return enums (or take them
by value); it just doesn't allow the functions to be called (or defined)
without the enum being complete.  This could be useful for private class
members:

  class foo
  {
   private:
    // Forward declaration of nested enum
    enum state_type;

    // And some member functions the use it
    state_type state() const;
    void apply( state_type, state_type );
  };

As long as state_type is defined in the corresponding source file, then the
public member functions defined in the source file can call the various
state functions, and the state functions can be implemented there too.

There are certainly times when I've wanted to be able to do this --
especially when the values in state_enum are frequently changed.

--
Richard Smith


---
[ 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                       ]