What does "Uint32 enum {a = 100, b = 200};" mean?

X

Xiangliang Meng

Hi, all.

I see a very strange fragment code today.

Uint32 enum
{
a = 100;
b = 200;
};
NOTE: Uint32 is defined to be 'unsigned' in other source files.

I'm sure that C standard does NOT premit to define an enumeration specifier
like this. In addition, I did not find that GNU CC has such extension to the
C Language, although this code is compiled by gcc. Therefore, I'm totally
confused by this fragment code.

Could someone explain it for me? Thanks.

Best Regards,

Xiangliang Meng
 
R

Richard Bos

Xiangliang Meng said:
I see a very strange fragment code today.

Strange indeed.
Uint32 enum
{
a = 100;
b = 200;
};
NOTE: Uint32 is defined to be 'unsigned' in other source files.

That is a syntax error. If there's a typedef in front of it, it defines
Uint32 as the enum in question, which would be strange in itself; since
there isn't, it simply is not valid C.

Richard
 
D

Dan Pop

In said:
I see a very strange fragment code today.

Uint32 enum
{
a = 100;
b = 200;
};
NOTE: Uint32 is defined to be 'unsigned' in other source files.

I'm sure that C standard does NOT premit to define an enumeration specifier
like this. In addition, I did not find that GNU CC has such extension to the
C Language, although this code is compiled by gcc. Therefore, I'm totally
confused by this fragment code.

Could someone explain it for me? Thanks.

As such, it is entirely useless, because it doesn't contain a tag and it
doesn't declare any object. As for the syntactic issue, let's ask the
compilers (after replacing Uint32 by unsigned int):

fangorn:~/tmp 391> gcc -ansi -pedantic test.c
test.c:1: warning: useless keyword or type name in empty declaration
fangorn:~/tmp 392> pgcc test.c
PGC-W-0114-More than one type specified (test.c: 1)
PGC-W-0150-Useless declaration (test.c: 1)
PGC/x86 Linux/x86 3.3-2: compilation completed with warnings
fangorn:~/tmp 393> icc test.c
test.c(1): error: invalid combination of type specifiers
unsigned int enum {a = 100, b = 200};
^

compilation aborted for test.c (code 2)

No compiler made any sense out of it, so how could I? ;-) Speculating:

4 Each enumerated type shall be compatible with char, a signed
integer type, or an unsigned integer type. The choice of type is
implementation-defined, but shall be capable of representing
the values of all the members of the enumeration.

So, it looks like an extension allowing the programmer to choose the
integer type himself, rather than leaving the choice up to the compiler.

Dan
 
C

Chris Torek

That is a syntax error. If there's a typedef in front of it, it defines
Uint32 as the enum in question ...

It is indeed a syntax error, but adding a "typedef" would not help
either, because the syntax for "typedef" is:

First, write an ordinary variable or function declarations.

int a;
char *b;
double c[2], d;

Each of these declares (and usually defines) the given identifier
as an object of the given type -- "a" has type "int", "b" has
type "char *", "c" has type "double [2]", and "d" has type
"double".

Next, stick a typedef in front:

typedef int a;
typedef char *b;
typedef double c[2], d;

(The last form is one that often surprises people.) These
change the lines from meaning "declare <name> as <object> with
type <type>" to "declare <name> as synonym for type <type>".
Hence, "a" is now a synonym for "int", "b" is now a synonym
for "char *", "c" is now a synonym for "double [2]", and "d"
is now a synonym for "double".

Now, if we do this for the "enum" above -- even after correcting
other problems like the improper semicolons -- it has the wrong
form:

/* should be: typedef <existing-type> <new-alias> */
typedef new_alias enum ...; /* wrong -- backwards! */

To give it the right form, the identifier has to come after the
"enum" sequence:

typedef enum optional_tag { a = 100, b = 200 } new_alias;

People get this backwards often, I speculate, from a perceived
(but false) symmetry with "#define":

#define DataType double /* new alias, then existing type */
typedef double DataType; /* existing type, then new alias */

Given the other syntax problems in Xiangliang Meng's original
posting, I suspect he was copying the "mystery declaration" from
(fuzzy) memory rather than the actual C source that used it.
 
K

Keith Thompson

Xiangliang Meng said:
I see a very strange fragment code today.

Uint32 enum
{
a = 100;
b = 200;
};
NOTE: Uint32 is defined to be 'unsigned' in other source files.

I'm sure that C standard does NOT premit to define an enumeration specifier
like this. In addition, I did not find that GNU CC has such extension to the
C Language, although this code is compiled by gcc. Therefore, I'm totally
confused by this fragment code.

Could someone explain it for me? Thanks.

No, gcc doesn't accept the above code. The semicolons are incorrect;
they should be commas (the second one is optional).

If you're going to post a code sample, please don't try to re-type it;
cut-and-paste the *exact* code that you've compiled. Otherwise, we
can't tell which errors are typos and which are relevant to your
question.

If I compile the following with gcc 3.3.3:

typedef unsigned Uint32;
Uint32 enum
{
a = 100,
b = 200
};

I get:

tmp.c:6: warning: useless keyword or type name in empty declaration

(I'm not sure why it's just a warning rather than an error message,
but the standard doesn't distinguish between different kinds of
diagnostics. I get the same warning with "int int;".)

If I change it to:

typedef unsigned Uint32;
Uint32 enum
{
a = 100,
b = 200
} obj;

I get:

tmp.c:6: error: two or more data types in declaration of `obj'

It looks like an attempt to create an enumeration type with a specific
representation, but it's not something that gcc supports.
 
D

Dan Pop

In said:
No, gcc doesn't accept the above code. The semicolons are incorrect;
they should be commas (the second one is optional).

Note that he got it right in the subject line.

Dan
 
X

Xiangliang Meng

Hi, all

Several points to address:

1. I could not copy and paste the original codes, due to company's policy.
";" should be "," in the content.

2. I consult an super expert on C++ in my company on this fragement code.
His opinion is:
" The original developer was hoping to control the underlying integral type
used to represent the enum. There is no official way to do this in the C/C++
standard. This tends to be a problem in C++ designs that overload methods
based on the signedness of integral types. This is considered poor design.

The 99r1 C compiler warns about this fragment. The 99r1 C++ compiler quietly
accepts the fragment (which I believe is a bug).

The gcc-3.3.1 C compiler warns about this fragment. The gcc-3.3.1 C++
compiler generates an error for this fragment."

3. I sent an email to one of their creators, but he could not remember why
he did that. Those codes were created ten years ago.

4. How those enumeration constant are used?
They defined some constant configuration parameters as these enumeration
constants. So they did not use the enum type to define any local variable,
but took them as constant and used them directly.

Thank all of you very much.

Best Regards,

Xiangliang Meng
 
M

Martin Ambuhl

Xiangliang Meng wrote:

2. I consult an super expert on C++ in my company on this fragement code.
His opinion is:
" The original developer was hoping to control the underlying integral type
used to represent the enum. There is no official way to do this in the C/C++
standard.

He is not even a moderate literate in C or C++, much less a "super
expert." A "super expert" knows that not only are C and C++ different
languages, they have completely different standards. There is no such
thing as "C/C++"; there is certainly no such thing as "the C/C++
standard". Rather, there are C and C++ standards. Don't believe
anything that comes out of his mouth.
 
X

Xiangliang Meng

Hi, Martin.

I think he just wanted to say "in the C standard or in the C++ standard".

Best Regards,

Xiangliang Meng
 
K

Keith Thompson

Martin Ambuhl said:
He is not even a moderate literate in C or C++, much less a "super
expert." A "super expert" knows that not only are C and C++ different
languages, they have completely different standards. There is no such
thing as "C/C++"; there is certainly no such thing as "the C/C++
standard". Rather, there are C and C++ standards. Don't believe
anything that comes out of his mouth.

That may a little harsh. In the jargon of this newsgroup, "C/C++"
refers to a mythical language with some undefined relationship to C
and/or C++, with the side effect of marking the person using the term
as ignorant. Out in the real world, "the C/C++ standard" could
conceivably mean "the C standard or the C++ standard".

It's clumsy and incorrect, but it may be just informal rather than
incurably ignorant.
 

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

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top