[comp.std.c] are enums integers in ANSI?

lai@vedge.UUCP (David Lai) (11/23/88)

C: A Reference Manual (Harbison and Steele) says:

	Draft Proposed ANSI C and most current implementations mandate
	that all enumeration types be treated as integer types, and that
	all enumeration constants appearing in expressions have type int.

Does this mean:

	int a;
	enum { abc, def} b;
	enum {ghi, jkl} c;

	b=a;
	a=b;
	a=abc;
	c=abc;
	b=c;

are legal, or are explicit casts necessary?  The sun compiler likes
to complain, will ANSI compilers complain?

-- 
	"What is a DJ if he can't scratch?"  - Uncle Jamms Army
The views expressed are those of the author, and not of Visual Edge, nor Usenet.
David Lai (vedge!lai@larry.mcrcim.mcgill.edu || ...watmath!onfcanim!vedge!lai)

henry@utzoo.uucp (Henry Spencer) (11/25/88)

In article <2005@vedge.UUCP> lai@vedge.UUCP (David Lai) writes:
>	Draft Proposed ANSI C and most current implementations mandate
>	that all enumeration types be treated as integer types...
>Does this mean:  [examples of promiscuous enumming]
>are legal, or are explicit casts necessary?  The sun compiler likes
>to complain, will ANSI compilers complain?

Enums are a fancy way of declaring an integer type and some integer
constants.  The language (at least as of the May draft, I haven't had
the time to study the October draft carefully yet) makes no finer
distinctions.  Casts are not needed.  Compilers are free to complain
about most anything they feel like complaining about, and it is quite
possible that many compilers will try to help out by producing warning
messages about what they consider sloppy use of enums.  Murphy being
what he is, probably no two such compilers will quite agree on what to
complain about...
-- 
Sendmail is a bug,             |     Henry Spencer at U of Toronto Zoology
not a feature.                 | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

dmr@alice.UUCP (11/26/88)

Enumeration constants are integer constants, and moreover must
have a value that is representable in type int.  

As Henry said, enum variables turn into ints in all expression
usages and may be freely assigned, passed, and have arithmetic
done on them without casts (see section 3.2.1.1).  I think even the
comments that used to appear in the Draft, saying that the compiler
might warn about mixing one enum type with another, are now gone.

However, enum types are not identical to other types; each enum
constitutes a distinct type (3.1.2.5).  On the other hand, each
enum type is compatible with some integral type (3.5.2.2) though
which one is implementation-defined.

"Compatible with" for types is an interesting (and complicated)
concept in ANSI C.  It is not an equivalence relationship because
it fails to be transitive.  It is used mainly to determine
when two declarations for the same name in a scope are
legal and refer to the same thing.  You can say

	int x[];
	int x[10];

because the types "incomplete array of int" and "array of 10 ints"
are compatible.

How does this relate to enums?  Well, for one thing, it is
never legal to declare

	struct s { enum e x:10; };

because, although enum e is compatible with some integral type,
it is not identical, and the type of a bitfield must be
(signed|unsigned) int. Thus, no enum bitfields.

Here is a more subtle example.

	int x;
	enum e x;

A compiler is permitted to accept this if, for example, it decides
that the integral type all enums are compatible with is int.

It is permitted to reject it also; in fact it may reject it even
if you try all the possibilities of char, unsigned, long, etc. instead
of int.  The reasoning (theoretically) is that the compiler doesn't
have to announce in advance just which variety of int is compatible
with a particular enum.  In effect, it is allowed to play the hostile
adversary, and choose a compatible integral type for this enum other than
the one you guessed!

			Dennis Ritchie
			dmr@research.att.com
			research!dmr

bill@twwells.uucp (T. William Wells) (11/27/88)

In article <8457@alice.UUCP> dmr@alice.UUCP writes:
: Here is a more subtle example.
:
:       int x;
:       enum e x;
:
: A compiler is permitted to accept this if, for example, it decides
: that the integral type all enums are compatible with is int.

That bothers me. I thought the purpose of the compatible/composite
stuff was to permit merging the types of arrays and functions.  It
seems a mistake to permit other than that. Are there reasons why this
is permitted? Or is this accidental?

: It is permitted to reject it also; in fact it may reject it even
: if you try all the possibilities of char, unsigned, long, etc. instead
: of int.  The reasoning (theoretically) is that the compiler doesn't
: have to announce in advance just which variety of int is compatible
: with a particular enum.  In effect, it is allowed to play the hostile
: adversary, and choose a compatible integral type for this enum other than
: the one you guessed!

But it does!  The standard says that which one it is compatible with
is "implementation defined". That implies that it has to be
documented.

Furthermore, if we accept that the notion, stated in the Rationale,
that "implementation defined" does not extend to failing to translate
the program, applies here, then there has to be at least *one*
declaration that will work.

---
Bill
{uunet|novavax}!proxftl!twwells!bill

henry@utzoo.uucp (Henry Spencer) (11/29/88)

In article <219@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes:
>: ... In effect, it is allowed to play the hostile
>: adversary, and choose a compatible integral type for this enum other than
>: the one you guessed!
>
>But it does!  The standard says that which one it is compatible with
>is "implementation defined". That implies that it has to be
>documented.

Yes, but this is not entirely inconsistent with Dennis's suggestion.
It's quite possible for the documentation to say "picks the first type
from the following list which can hold the values and is not the one used
in any other declaration of this variable:  char, int, [...]".  Many of
the things which are implementation-defined will have to be documented
as algorithms, not single choices, and there is nothing which forbids
perverse algorithms.

>Furthermore, if we accept that the notion, stated in the Rationale,
>that "implementation defined" does not extend to failing to translate
>the program, applies here, then there has to be at least *one*
>declaration that will work.

No; what we have here is a situation in which the legality of such a
program is implementation-defined.  It is not improper to fail to translate
an illegal program.
-- 
SunOSish, adj:  requiring      |     Henry Spencer at U of Toronto Zoology
32-bit bug numbers.            | uunet!attcan!utzoo!henry henry@zoo.toronto.edu