I believe that the standard's text allows this code, and defines the effects.
However, I think vaguely recall that there was an interpretation ruling on
this -- but I can't find it in my list of interpretation questions now.
> I would think you could, since incomplete types can be typedef'd
I believe that the following examples are not allowed because there is
no such thing as an incomplete enum type.
typedef enum class_id class_id;
class_id *x;
enum class_id { first_val, second_val, etc };
and
typedef enum class_id class_id;
class_id x;
enum class_id { first_val, second_val, etc };
>and enums have known size (i.e. sizeof(int))
I don't think so. Each enumeration constant has type int, but enumeration
types are not so precisely constrained. I believe that someone plans to
submit defect reports asking for clarification of this matter.
--
<< If this were the company's opinion, I would not be allowed to post it. >>
A program in conformance will not tend to stay in conformance, because even if
it doesn't change, the standard will. Force = program size * destruction.
Every technical corrigendum is met by an equally troublesome new defect report.
I believe this is undefined, because the semantics section of 6.5.2.3
does not include this specific format. However, no constraint is
violated and no diagnostic is required.
--
Clive D.W. Feather | IXI Ltd (an SCO company) | If you lie to the compiler,
cl...@x.co.uk | Vision Park | it will get its revenge.
Phone: +44 223 236 555 | Cambridge CB4 4ZR | - Henry Spencer
Fax: +44 223 236 466 | United Kingdom |
Yes; in Footnote 62, as someone previously pointed out, "a similar
construction with _enum_ does not exist" on the grounds that there are no
mutual dependencies among enums. What they didn't seem to take into account is
that the standard doesn't appear to enforce the idea that all enum types must
share a common type.
> typedef enum class_id class_id;
> class_id *x;
> enum class_id { first_val, second_val, etc };
>and
> typedef enum class_id class_id;
> class_id x;
> enum class_id { first_val, second_val, etc };
>
>>and enums have known size (i.e. sizeof(int))
>
>I don't think so. Each enumeration constant has type int, but enumeration
>types are not so precisely constrained. I believe that someone plans to
>submit defect reports asking for clarification of this matter.
ANSI X3.159-1989, Section 3.5.2.2, Lines 32-33, says that "The
identifiers in an enumerator list are declared as constants that have type int
and may appear wherever such are permitted." Lines 40-41 say that "Each
enumerated type shall be compatible with an integer type; the choice of type is
implementation-defined."
What ANSI X3.159-1989 seems to be saying, then, is that the fundamental
type representing Joe Enum is determined at the time of Joe Enum's definition,
and in an implementation-defined manner.
I am not so sure about what the meaning of the phrase "Each enumerated
type shall be compatible with an integer type" means, though. ANSI
X3.159-1989, Section 3.1.2.6, Line 2 says that "Two types have compatible type
if their types are the same." (I'm not sure whether that should be read as "A
<--> B" or "A <-- B". "A <--> B" seems too strong.) Furthermore, I doubt that
a type can have a type, but that's what that sentence implies.
ANSI X3.159-1989, Section 3.1.2.6 refers the reader to Sections 3.5.2,
3.5.3, and 3.5.4 for additional rules, but I can't find anything that covers
the enum case that started this thread. (I might have missed something.)
A clarification sure would be nice. Do you know who's putting together
the defect report? Does he/she have an electronic mail address?
--
John Davison, davi...@ecn.purdue.edu <---- send followups to THIS ADDRESS!!!!!
(Otherwise your mail will bounce!) If you work at NT/BNR, please COCOS to
"John Davison". The information contained in this article isn't necessarily
representative of Northern Telecom or BNR.
I believe the meaning is quite clear. In fact, I have developed a simple
method whereby the integral type which a compiler considers to be
compatible with one particular (small) enum type may be determined.
My method involves the use of a rather clever makefile which iteratively
compiles the following file with the preprocessor symbol TYPE defined to
each of the possible (standard) built-in integral types. This iteration
continues until one definition is found for which the compiler being used
issues no errors for this small piece of code.
Note that if *all* definitions of TYPE (from the set `char', `signed char',
`unsigned char', `short', `unsigned short', int, `unsigned int', `long',
`unsigned long') produce compilation errors on this example, then the
compiler in question is not fully standard conforming.
-- rfg
=============================================================================
/* (C) 1993 Ronald F. Guilmette; all rights reserved. */
/* This file is used (by the Config/Makefile) to determine which integral
type is considered (by the implementation) to be compatible with small
(i.e. < 256 elements) enum types.
The mechanism we use to do this is rather ugly, but there is not other
easy way to get this bit of information accurately. Basically, we try
compiling this file with different definitions of the preprocessor
symbol TYPE until we find one which DOES NOT cause a compile-time error.
The definitions we try for TYPE are just the names of all of the
standard C integral types.
*/
enum COLOR { red, green, blue };
enum COLOR variable;
TYPE variable;
--
-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: r...@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
>I believe this is undefined, because the semantics section of 6.5.2.3
>does not include this specific format.
I previously posted an opinion that this is valid, though it would not
be valid if Mr. Davison had tried declaring an object of type class_id
or even (class_id*) between the two declarations.
Mr. Feather's answer troubles me. It is true that no semantics are
specified for the first declaration of the enum tag. However, the syntax
permits it, and no part of the text, none at all, makes any effort to
override it. I believe that there are simply no semantics, that the first
declaration has no effect on the tag class_id, that the result is the same
as if it were omitted and the ordinary identifier (type name) class_id had
been declared by a latter typedef.
For comparison, Mr. Davison's second declaration declares no objects, and
the sections on declaring objects have no semantics for that specific
format, but none are needed. No objects of type enum class_id are declared.
What is the type represented by the identifier "class_id" after the first
line ? It cannot be the enumerated type "enum { first_val, second_val, etc }"
because that type does not yet exist. It cannot be an incomplete type,
because incomplete types can only be arrays, structures, or unions. Thus
there is no standard-defined type which it can have, and so the type is
undefined.
> For comparison, Mr. Davison's second declaration declares no objects, and
> the sections on declaring objects have no semantics for that specific
> format, but none are needed.
Oh yes they do. 6.5.2.3, first few lines:
A type specifier of the form
struct-or-union identifier { struct-declaration-list }
or
enum identifier { enumeration-list }
declares ...
It then says that, once the tag has been declared, the omitted list may
(and in the same scope must) be omitted.
There are also defined semantics for:
struct-or-union identifier
struct-or-union identifier ;
struct-or-union { struct-declaration-list }
and
enum identifier { enumeration-list }
in the same section.
However, there are no defined semantics for the case of:
enum identifier
where the tag is not already declared. Therefore, I claim, there are no
semantics for this construction, and it is therefore undefined.
I repeat that there is no constraint being violated, and no diagnostic
is required. A compiler could "do the right thing" here - it is merely
not required to. I see absolutely no evidence for your view, and I don't
see any need for an interpretation request.