Question about enum


L

Lew Pitcher

In alt.os.linux, I just encountered a post regarding debugging of a C
program (source supplied). I won't trouble the group with the code in
question, but I do have a question of my own about the code.

The programmer had written something like...

typedef enum { false, true } bool;

int TheFunction(argument)
int argument;
{
int inword;

inword = true;
/* other logic followed */
}

Is this use of an enum constant valid? To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

What do the C experts here think? Am I wrong to be suspicious of the
OP's typedef and code, or is this really valid C? (Note that both the
original code and my subset example above were coded in K&R C).
 
Ad

Advertisements

E

Eric Sosman

In alt.os.linux, I just encountered a post regarding debugging of a C
program (source supplied). I won't trouble the group with the code in
question, but I do have a question of my own about the code.

The programmer had written something like...

typedef enum { false, true } bool;

int TheFunction(argument)
int argument;
{
int inword;

inword = true;
/* other logic followed */
}

Is this use of an enum constant valid? To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

What do the C experts here think? Am I wrong to be suspicious of the
OP's typedef and code, or is this really valid C? (Note that both the
original code and my subset example above were coded in K&R C).

Well, not quite: "The C Programming Language" (K&R, 1978) has no
`enum' construct. It appeared soon after (and I could have sworn
it was mentioned as "coming soon" in K&R, but I can't find it at the
moment), but it wasn't in what's known as the "base document" for C.

But that's a rat hole. "ANSI" C certainly has `enum', and has
support for the K&R-style function definition. Under ANSI/C89/C90
rules I see nothing wrong with the code you've shown. Both `false'
and `true' are `int' constants in whatever context, even with no
`bool' in the immediate vicinity. `exit(false)' would terminate
the program successfully; `malloc(true)' would try to allocate one
byte, `++x' and `x+=true' would be exactly equivalent.

Anecdote: I once ran across

typedef enum { TRUE, FALSE } Boolean;

.... in somebody else's code. "Mit der Dummheit kämpfen Götter selbst
vergebens." -- Schiller
 
S

Shao Miller

In alt.os.linux, I just encountered a post regarding debugging of a C
program (source supplied). I won't trouble the group with the code in
question, but I do have a question of my own about the code.

The programmer had written something like...

typedef enum { false, true } bool;

int TheFunction(argument)
int argument;
{
int inword;

inword = true;
/* other logic followed */
}

Is this use of an enum constant valid? To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

What do the C experts here think? Am I wrong to be suspicious of the
OP's typedef and code, or is this really valid C? (Note that both the
original code and my subset example above were coded in K&R C).

There's no 'bool' nor 'true' nor 'false' in "ANSI C," that I know of.
If that's the conformed-to Standard, then this seems fine.

I believe that 'false' and 'true' will be the 'int' values '0', and '1',
respectively.

The 'bool' type could be any implementation-defined integer type, I
think. 'unsigned char' might be handy, given these values, but there's
no obligation.

I'd be a bit worried about this code being compiled by a C99-conforming
[mode] implementation if <stdbool.h> was included. That header
'#define's 'bool' to '_Bool', 'false' to '0', 'true' to '1'.

One can use tag-less enums to produce 'int' constants in general, as far
as I know.

enum {
foo = 42,
bar = 13,
zero = 0
};

An odd pattern might be:

/** my_func: Blah blah blah... */
enum {
/* Return codes */
status_success,
status_out_of_memory,
status_invalid_parameter,
status_not_supported,
status_unknown_error

} my_func(
/* Parameters */
void * ptr

) {
/* Function body... */
return status_success;
}
 
S

S R

The programmer had written something like...

    typedef enum { false, true } bool;

    int TheFunction(argument)
    int argument;
    {
      int  inword;

      inword = true;
      /* other logic followed */
    }

Is this use of an enum constant valid? To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
  bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

[snip]

The use of the enumerated constant under this context is valid (as
others have pointed out). From the standard (I currently have access
to 1256.pdf and hence I quote from it)

6.7 p5

A declaration specifies the interpretation and attributes of a set of
identifiers. A definition
of an identifier is a declaration for that identifier that:
— for an object, causes storage to be reserved for that object;
— for a function, includes the function body;101)
— *for an enumeration constant or typedef name, is the (only)
declaration of the
identifier.*

6.2.1 p7
Structure, union, and enumeration tags have scope that begins just
after the appearance of
the tag in a type specifier that declares the tag. *Each enumeration
constant has scope that
begins just after the appearance of its defining enumerator in an
enumerator list*. Any
other identifier has scope that begins just after the completion of
its declarator.

The sentences marked with * should clear up the doubt you have. The
presence of a typedef has an effect on what bool is.
 
J

James Kuyper

In alt.os.linux, I just encountered a post regarding debugging of a C
program (source supplied). I won't trouble the group with the code in
question, but I do have a question of my own about the code.

The programmer had written something like...

typedef enum { false, true } bool;

int TheFunction(argument)
int argument;
{
int inword;

inword = true;
/* other logic followed */
}

Is this use of an enum constant valid? To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

In C, virtually anywhere that you can specify a type, that specification
could be the one that also defines a new user-defined type (an
enumeration, union, or struct). You can do this inside a function
declaration when specifying the return or parameter types. You can also
do this inside of cast, sizeof, or compound literal expressions.

Note that most of the above possibilities are disallowed in C++, because
the designer of C++ thought that taking advantage of those possibilities
was bad practice. However, even in C++ definition of a new type is
allowed inside a typedef statement.
 
S

Seebs

The programmer had written something like...

typedef enum { false, true } bool;

int TheFunction(argument)
int argument;
{
int inword;

inword = true;
/* other logic followed */
}
Is this use of an enum constant valid?
Yes.

To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

This doesn't make any sense.

enum constants are not in any way "scoped" to the enumerated type they're
used for. If an enumerated type has been declared using particular
values, then those values are available.
What do the C experts here think? Am I wrong to be suspicious of the
OP's typedef and code, or is this really valid C? (Note that both the
original code and my subset example above were coded in K&R C).

So far as I know this has been valid for as long as both enum and typedef
have existed. It was not valid in compilers that did not have both enum
and typedef, for obvious reasons.

-s
 
Ad

Advertisements

K

Keith Thompson

Lew Pitcher said:
In alt.os.linux, I just encountered a post regarding debugging of a C
program (source supplied). I won't trouble the group with the code in
question, but I do have a question of my own about the code.

The programmer had written something like...

typedef enum { false, true } bool;

int TheFunction(argument)
int argument;
{
int inword;

inword = true;
/* other logic followed */
}

Is this use of an enum constant valid? To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

What do the C experts here think? Am I wrong to be suspicious of the
OP's typedef and code, or is this really valid C? (Note that both the
original code and my subset example above were coded in K&R C).

The enum constant ``true'' acts like an integer costant with the
value 1. (Note that it's of type int, not of type bool; that's
a rather odd quirk of the C language, but it doesn't cause any
problems here.

As a matter of style, it's odd that the author defined a "bool" type,
but then declared inword, which presumably is intended only to old the
values "false" and "true"", as an int.

(The code is perfectly valid in C99, as long as there's no
"#include <stdbool.h>".)
 
J

Joe Pfeiffer

Keith Thompson said:
The enum constant ``true'' acts like an integer costant with the
value 1. (Note that it's of type int, not of type bool; that's
a rather odd quirk of the C language, but it doesn't cause any
problems here.

As a matter of style, it's odd that the author defined a "bool" type,
but then declared inword, which presumably is intended only to old the
values "false" and "true"", as an int.

(The code is perfectly valid in C99, as long as there's no
"#include <stdbool.h>".)

Something I haven't seen brought up is that one should look at the code
of somebody who will define a bool enum, but then declare a variable as
an int in order to use values from the enum, with a raised eyebrow.
There's nothing "wrong" with the code, but you do have to wonder how
well thought out it is.
 
K

Keith Thompson

Joe Pfeiffer said:
Something I haven't seen brought up is that one should look at the code
of somebody who will define a bool enum, but then declare a variable as
an int in order to use values from the enum, with a raised eyebrow.
There's nothing "wrong" with the code, but you do have to wonder how
well thought out it is.

I find it odd that you say you haven't seen it brought up, while quoting
my article in which I brought it up.
 
J

Joe Pfeiffer

Keith Thompson said:
I find it odd that you say you haven't seen it brought up, while quoting
my article in which I brought it up.

You point out, rightly, that it's odd -- my point is that there's likely
to be some more seriously bad and badly-done stuff in there, too.
Possibly it was too obvious an extension for others to mention...
 
Ad

Advertisements

M

Malcolm McLean

In alt.os.linux, I just encountered a post regarding debugging of a C
program (source supplied). I won't trouble the group with the code in
question, but I do have a question of my own about the code.

The programmer had written something like...

    typedef enum { false, true } bool;

    int TheFunction(argument)
    int argument;
    {
      int  inword;

      inword = true;
      /* other logic followed */
    }

Is this use of an enum constant valid? To me, the enum shouldn't
"exist" in that it acts like a "template" courtesy of the typedef. Had
the author included a
  bool something;
then the enum would, in my mind, "exist" wrt the code at hand.

What do the C experts here think? Am I wrong to be suspicious of the
OP's typedef and code, or is this really valid C?  (Note that both the
original code and my subset example above were coded in K&R C).
Basically an enumerated type isn't an integer. The problem is that
eventually you often have to treat it as an integer, both because C
wasn't built with enums as an inherent part of the language (you can't
print an enum's identifier, for instance), and because we often don't
actually want the numbers associated with enums to be arbitrary, you
might want compass directions to go clockwise, for example, so you can
rotate by adding or subtracting.
So assigning an enum to an int is allowed. Really it breaks the idea
of enums, however.
 
S

Stephen Sprunk

As a matter of style, it's odd that the author defined a "bool" type,
but then declared inword, which presumably is intended only to old the
values "false" and "true"", as an int.

I found that odd as well but assumed the code originally had #defintes
for true and false that were later "upgraded" to an enum. I've seen
similar things before.

I wish C's type system drew more of a distinction between enums and
ints, but to change that now would break too much working code.

S
 
D

Dr Nick

Stephen Sprunk said:
I found that odd as well but assumed the code originally had #defintes
for true and false that were later "upgraded" to an enum. I've seen
similar things before.

I wish C's type system drew more of a distinction between enums and
ints, but to change that now would break too much working code.

Though, of course, in another thread we've got people advocating using
enums for symbolic integer constants.

It's certainly one of those "I wouldn't start from here" things that C
is a big cluttered up with.
 
I

Ian Collins

I found that odd as well but assumed the code originally had #defintes
for true and false that were later "upgraded" to an enum. I've seen
similar things before.

I wish C's type system drew more of a distinction between enums and
ints, but to change that now would break too much working code.

C++ has many (but not all) of the same issues with enums which is why
the new standard has scoped strongly typed enums. Maybe something else
that could cross-pollinate C?
 
S

Stephen Sprunk

Though, of course, in another thread we've got people advocating using
enums for symbolic integer constants.

Doing that is arguably better than using #defines, but IMHO the correct
solution is to declare const ints to be constant integer expressions, as
any sane person would expect.

Once that particular (ab)use of enums were no longer necessary, we could
declare that there is no implicit conversion between ints and enums or
between different types of enums.

S
 
Ad

Advertisements

K

Keith Thompson

Stephen Sprunk said:
Doing that is arguably better than using #defines, but IMHO the correct
solution is to declare const ints to be constant integer expressions, as
any sane person would expect.

Once that particular (ab)use of enums were no longer necessary, we could
declare that there is no implicit conversion between ints and enums or
between different types of enums.

Right, and then it would be a simple matter of modifying all the code
that depends on the current behavior.
 
Ad

Advertisements

P

Peter Nilsson

Lew Pitcher said:
...The programmer had written something like...

typedef enum { false, true } bool;

int TheFunction(argument)
int argument;
{
int inword;

inword = true;
/* other logic followed */
}

Is this use of an enum constant valid? To me, the enum
shouldn't "exist" in that it acts like a "template" courtesy
of the typedef.

What could really bake your noodle is when you replace the
typedef with...

int quux = sizeof( enum { false, true } );

....the assignment to inword still works.

Specifying a type specifies a type!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top