an enum and ntoh question

P

poison.summer

Hello

If I have an enum definition
for instance

typedef enum {
F0 = 0,
F1 = 1,
F2 = 2,
F3 =3
} Ftest;

Ftest a;
and I need to do ntoh, which one to use ntohl or ntohs?

And do I have to cast it back to Ftest?

Thanks a lot!
 
V

Vladimir S. Oka

Hello

If I have an enum definition
for instance

typedef enum {
F0 = 0,
F1 = 1,
F2 = 2,
F3 =3
} Ftest;

Ftest a;
and I need to do ntoh, which one to use ntohl or ntohs?

And do I have to cast it back to Ftest?

Your question is off topic, ntoh*() and hton*() functions not being part
of Standard C.

Also, your question does not seem to be too well framed.

What I think you're asking may be what's the `type` of an `enum`. Well,
the Standard specifies that it has to fit in an `int`. Now, look up how
your functions are declared, and you'll figure out (or not) what to do.
It seems to depend on the size of your `int`.

Cheers

Vladimir
 
S

SM Ryan

(e-mail address removed) wrote:
# Hello
#
# If I have an enum definition
# for instance
#
# typedef enum {
# F0 = 0,
# F1 = 1,
# F2 = 2,
# F3 =3
# } Ftest;
#
# Ftest a;
# and I need to do ntoh, which one to use ntohl or ntohs?

Why guess? Cast it and you don't have to worry. What are you using it for?
Do you need a long or short result?

# And do I have to cast it back to Ftest?

Ftest is just another integer.
 
V

Vladimir S. Oka

SM said:
(e-mail address removed) wrote:
# Hello
#
# If I have an enum definition
# for instance
#
# typedef enum {
# F0 = 0,
# F1 = 1,
# F2 = 2,
# F3 =3
# } Ftest;
#
# Ftest a;
# and I need to do ntoh, which one to use ntohl or ntohs?

Why guess? Cast it and you don't have to worry. What are you using it for?
Do you need a long or short result?

# And do I have to cast it back to Ftest?

Ftest is just another integer.

No, it's not, it's a new type called `Ftest`, which is actually an
`enum`. The fact that enums can be represented as ints (as the Standard
assures us) doe snot mean that enums /are/ ints. They're a completely
different beast.

Cheers

Vladimir
 
T

tmp123

Hello

If I have an enum definition
for instance

typedef enum {
F0 = 0,
F1 = 1,
F2 = 2,
F3 =3
} Ftest;

Ftest a;
and I need to do ntoh, which one to use ntohl or ntohs?

And do I have to cast it back to Ftest?

Thanks a lot!

Ftest is in the range [0,3], that fits in an uint16, thus ntohs/htons.
 
C

Chris Torek

No, it's not, it's a new type called `Ftest`, which is actually an
`enum`. The fact that enums can be represented as ints (as the Standard
assures us) doe snot mean that enums /are/ ints. They're a completely
different beast.

Well, more specifically, they are compatible with an integer
type -- we just are not told which one (and compilers can
change "which one" more or less at whim, too).

Peculiarly, however, enumeration *constants* have type "int".

Since the constants have type "int", the only types that really
make sense, as compiler choices, for the enumerated types, are
char, signed char, unsigned char, short, unsigned short, and int.
(Well, in C99, a compiler can use an "extended" type, including
types halfway between char and short for instance -- one might
do this on a Cray, where "char" is 8 bits but "short" is 64.)
 
K

Keith Thompson

Chris Torek said:
Well, more specifically, they are compatible with an integer
type -- we just are not told which one (and compilers can
change "which one" more or less at whim, too).

Peculiarly, however, enumeration *constants* have type "int".

Since the constants have type "int", the only types that really
make sense, as compiler choices, for the enumerated types, are
char, signed char, unsigned char, short, unsigned short, and int.

Though a sufficiently perverse compiler could make an enumerated type
compatible with signed or unsigned long or long long.
(Well, in C99, a compiler can use an "extended" type, including
types halfway between char and short for instance -- one might
do this on a Cray, where "char" is 8 bits but "short" is 64.)

One probably wouldn't, though; the reasons for "short" being 64 bits
(that the hardware can't directly access quantities smaller than 64
bits) apply equally to enumerated types. (This applies only to *some*
Cray systems, BTW.)
 
T

Thad Smith

Vladimir S. Oka said:
Your question is off topic, ntoh*() and hton*() functions not being part
of Standard C.

Also, your question does not seem to be too well framed.

What I think you're asking may be what's the `type` of an `enum`. Well,
the Standard specifies that it has to fit in an `int`.

While that's true, there's a subtlety involved: a specific enumeration
type may be stored in a implementation-defined compatible integer type
smaller than an int. It then has the same rank as the compatible
integer type.
Now, look up how
your functions are declared, and you'll figure out (or not) what to do.
It seems to depend on the size of your `int`.

Not necessarily. A specific enumeration type may stored in a short.
The value of the variable should be limited to range of values in the
defined members of the type.
 
J

Jordan Abel

While that's true, there's a subtlety involved: a specific enumeration
type may be stored in a implementation-defined compatible integer type
smaller than an int. It then has the same rank as the compatible
integer type.

What if there are more than INT_MAX+1 items in the enumeration? Is an
implementation required to reject these, or may it choose long as the
integer type? Or is there undefined behavior?
 
C

CBFalconer

Jordan said:
.... snip ...

What if there are more than INT_MAX+1 items in the enumeration?
Is an implementation required to reject these, or may it choose
long as the integer type? Or is there undefined behavior?

Ridiculous. That would mean that someone, somewhere, spend
considerable time typing in at least 32767 unique identifiers into
the enum definition statement. The result would exceed the
standard guaranteed size availability for compiler input lines.

Don't worry your pretty little head about it.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 
T

Thad Smith

Jordan said:
What if there are more than INT_MAX+1 items in the enumeration? Is an
implementation required to reject these, or may it choose long as the
integer type? Or is there undefined behavior?

No, an implementation is not required to reject a declaration with
more than INT_MAX+1 enumeration constants. If the number of declared
enumeration constants exceeds the translator limit, a diagnostic
/should/ be issued (sorry, no C&V).

An implementation must support at least 1023 enumeration constants
(items) for a single enumeration. It may support more. Because there
may be separate enumeration constants with the same value and
enumeration constants can have assigned values, the number of
enumeration constants in an enumeration type is independent of the
range of values.

Although enumeration constants have type int, a specific enumeration
type may have a smaller range of values, be stored in a smaller int
type, and have a lesser rank. Standard C only supports enumeration
values within the range for type int. Attempting to specify an
enumeration constant with a value outside the range of an int violates
a constraint and requires a diagnostic. A conforming implementation
could still support larger values and provide sufficient storage for
the declared range, but it must still issue the diagnostic (in
conforming mode).
 
K

Keith Thompson

Jordan Abel said:
What if there are more than INT_MAX+1 items in the enumeration? Is an
implementation required to reject these, or may it choose long as the
integer type? Or is there undefined behavior?

C99 6.7.2.2p2 (a constraint) says:

The expression that defines the value of an enumeration constant
shall be an integer constant expression that has a value
representable as an int.

6.7.2.2p3 says:

The identifiers in an enumerator list are declared as constants
that have type int and may appear wherever such are permitted.

I don't see an explicit statement about this case:

#include <limits.h>
enum { foo = INT_MAX, bar };

where an enumerator has a value not representable as an int, but
there's no expression defining it -- but it seems reasonable to assume
that it's an error. (It's undefined behavior at the very least.)
 
K

Keith Thompson

CBFalconer said:
Ridiculous. That would mean that someone, somewhere, spend
considerable time typing in at least 32767 unique identifiers into
the enum definition statement. The result would exceed the
standard guaranteed size availability for compiler input lines.

Not at all. C code doesn't have to be typed manually; in fact,
automatically generated C code is quite common. And there's no reason
a huge enumeration type has to be declared on a single line.

#include <stdio.h>
int main(void)
{
long i;
printf("enum really_big {\n");
for (i = 0; i <= 32768; i ++) {
printf(" x%05d,\n", i);
}
printf("}\n");
return 0;
}

And of course you can achieve the same effect by specifying values for
the enumerators:

enum not_quite_as_big {
x00000 = 0,
x32768 = 32768,
};

The latter is a constraint violation if INT_MAX==32767; see my
response elsethread for chapter and verse.
 
M

Malcolm

Keith Thompson said:
Not at all. C code doesn't have to be typed manually; in fact,
automatically generated C code is quite common. And there's no reason
a huge enumeration type has to be declared on a single line.
But the whole point of an enum is to make code humanly readable.

Granted, sometimes automatically generated code is designed to be read, but
if it has 32767 types in an enumeration?
 

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

Staff online

Members online

Forum statistics

Threads
474,175
Messages
2,570,942
Members
47,489
Latest member
BrigidaD91

Latest Threads

Top