473,320 Members | 1,744 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

typedef declares object / enum to int

This post asks two questions, which I've illustrated in one C source file
(see below), which clean compiles on my GNU compiler.

1. In K&R2, Section A8.9 it says "Declarations whose storage class specifier
is typedef do not declare object." When I compile and run my sample code,
the value "2" is displayed. Clearly the typedef has created the enumerators
S1, S2, and S3. This appears to contradict K&R2.

2. The program below was created to emulate a Lint diagnostic I got in a
much larger project. In that project, the equivalent line to fn(SYMBOL)
gives the warning

Converting enum '{...}' to int

which I find puzzling. Enumerators are int anyway, whereas the enumeration
has an integral value (according to K&R2, Section A4.4). A warning about an
enumerator (int) being converted to an int seems meaningless; and a warning
about the enumeration (integral type) being converted to int doesn't make
sense because it's the enumerator S3 that gets
passed to fn(). I've reproduced Lint's explanation of the warning below.

/* typedef declaration; Lint warning */
#include <stdio.h>

typedef enum { S1, S2, S3 } an_enum_t;

#define SYMBOL S3

typedef unsigned int Word;
void fn(Word w)
{
/* deliberately empty */
}

int main( void )
{

fn(SYMBOL);
printf("%i\n", SYMBOL);
return 0; /* success */
}

This is Lint's description of the warning:

641 Converting enum to int -- An enumeration type was used in a context that
required a computation such as an argument to an arithmetic operator or was
compared with an integral argument. This warning will be suppressed if you
use the integer model of enumeration (+fie) but you will lose some valuable
type-checking in doing so. An intermediate policy is to simply turn off this
warning. Assignment of int to enum will still be caught.

This warning is not issued for a tagless enum without variables. For example

enum {false,true};

This cannot be used as a separate type. PC-lint/FlexeLint recognizes this
and treats false and true as arithmetic constants.

--
Martin

Nov 14 '05 #1
13 6504
"Martin" <martin.o_brien@[no-spam]which.net> writes:
1. In K&R2, Section A8.9 it says "Declarations whose storage class specifier
is typedef do not declare object." When I compile and run my sample code,
the value "2" is displayed. Clearly the typedef has created the enumerators
S1, S2, and S3. This appears to contradict K&R2.
Enumeration values are not objects. Objects are regions of
storage, but enumeration values are just values.
2. The program below was created to emulate a Lint diagnostic I got in a
much larger project. [...]


I've never been impressed with lint diagnostics. Often they
don't make a whole lot of sense in context, as you've discovered.
--
"The fact that there is a holy war doesn't mean that one of the sides
doesn't suck - usually both do..."
--Alexander Viro
Nov 14 '05 #2
Martin wrote:
This post asks two questions, which I've illustrated in one C source file
(see below), which clean compiles on my GNU compiler.

1. In K&R2, Section A8.9 it says "Declarations whose storage class specifier
is typedef do not declare object." When I compile and run my sample code,
the value "2" is displayed. Clearly the typedef has created the enumerators
S1, S2, and S3. This appears to contradict K&R2.
Enumeration constants are exactly that: Constants.
They are not objects.
2. The program below was created to emulate a Lint diagnostic I got in a
much larger project. In that project, the equivalent line to fn(SYMBOL)
gives the warning

Converting enum '{...}' to int

which I find puzzling. Enumerators are int anyway, whereas the enumeration
has an integral value (according to K&R2, Section A4.4). A warning about an
enumerator (int) being converted to an int seems meaningless; and a warning
about the enumeration (integral type) being converted to int doesn't make
sense because it's the enumerator S3 that gets
passed to fn(). I've reproduced Lint's explanation of the warning below.
To clarify:
Every enumerated type is distinct from every other enumerated or
integer type but is compatible to either char or a signed or unsigned
integer type. IOW: While the identifier S3 gives you a constant of type
int, the underlying enumerated type is not necessarily int.
Cheers
Michael /* typedef declaration; Lint warning */
#include <stdio.h>

typedef enum { S1, S2, S3 } an_enum_t;

#define SYMBOL S3

typedef unsigned int Word;
void fn(Word w)
{
/* deliberately empty */
}

int main( void )
{

fn(SYMBOL);
printf("%i\n", SYMBOL);
return 0; /* success */
}

This is Lint's description of the warning:

641 Converting enum to int -- An enumeration type was used in a context that
required a computation such as an argument to an arithmetic operator or was
compared with an integral argument. This warning will be suppressed if you
use the integer model of enumeration (+fie) but you will lose some valuable
type-checking in doing so. An intermediate policy is to simply turn off this
warning. Assignment of int to enum will still be caught.

This warning is not issued for a tagless enum without variables. For example

enum {false,true};

This cannot be used as a separate type. PC-lint/FlexeLint recognizes this
and treats false and true as arithmetic constants.

--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #3
Martin wrote:
This post asks two questions, which I've illustrated in one C source file
(see below), which clean compiles on my GNU compiler.

1. In K&R2, Section A8.9 it says "Declarations whose storage class specifier
is typedef do not declare object." When I compile and run my sample code,
the value "2" is displayed. Clearly the typedef has created the enumerators
S1, S2, and S3. This appears to contradict K&R2.
No!
S1, S2 and S3 are *values* that an object of type an_enum_t can have.
They are *not* themselves objects.
2. The program below was created to emulate a Lint diagnostic
[that] I got in a much larger project.
In that project, the equivalent line to fn(SYMBOL) gives the warning

Converting enum '{...}' to int

which I find puzzling. Enumerators are int anyway, whereas the enumeration
has an integral value (according to K&R2, Section A4.4). A warning about an
enumerator (int) being converted to an int seems meaningless;
and a warning about the enumeration (integral type) being converted to int
doesn't make sense because it's the enumerator S3 that gets passed to fn().
I've reproduced Lint's explanation of the warning below. cat main.c // typedef declaration; Lint warning
#include <stdio.h>

typedef enum { S1, S2, S3 } an_enum_t;

#define SYMBOL S3

typedef unsigned int Word;

void fn(Word w) {
// deliberately empty
}

int main(int argc, char* argv[]) {
fn(SYMBOL);
printf("%i\n", SYMBOL);
return 0; // success
}
gcc -Wall -std=c99 -pedantic -o main main.c
./main 2

This is Lint's description of the warning:

641 Converting enum to int -- An enumeration type was used in a context that
required a computation such as an argument to an arithmetic operator or was
compared with an integral argument. This warning will be suppressed if you
use the integer model of enumeration (+fie) but you will lose some valuable
type-checking in doing so. An intermediate policy is to simply turn off this
warning. Assignment of int to enum will still be caught.

This warning is not issued for a tagless enum without variables. For example

enum {false,true};

This cannot be used as a separate type. PC-lint/FlexeLint recognizes this
and treats false and true as arithmetic constants.


So your complaint is that lint is nitpicking?
Nov 14 '05 #4
"Ben Pfaff" wrote:
Enumeration values are not objects. Objects are
regions of storage, but enumeration values are
just values.
"just values"? I'm not sure I understand. Surely S1, S2, and S3 are
identifiers representing integer constants.

I think I'm surprised that the program even understands what S3 is and can
print it out, because no variable of type an_enum_t has been declared.

I've never been impressed with lint diagnostics. Often they
don't make a whole lot of sense in context, as you've discovered.


I do find it puzzling. I don't really understand what Lint sees as the
problem.

--
Martin

Nov 14 '05 #5
"Michael Mair" wrote:
To clarify:
Every enumerated type is distinct from every other enumerated or integer
type but is compatible to either char or a signed or unsigned integer
type. IOW: While the identifier S3 gives you a constant of type
int, the underlying enumerated type is not
necessarily int.


But I'm passing the identifier S3 to function fn(), and S3 is the identifier
of an integer constant. By all means warn me I'm passing an int to a
function expecting unsigned int, but what does " Converting enum '{...}' to
int" supposed to mean?

--
Martin

Nov 14 '05 #6
"E. Robert Tisdale" wrote:
So your complaint is that lint is nitpicking?


I'm not complaining. I'm seeking clarification.

--
Martin

Nov 14 '05 #7
"Martin" <martin.o_brien@[no-spam]which.net> writes:
"Ben Pfaff" wrote:
Enumeration values are not objects. Objects are
regions of storage, but enumeration values are
just values.


"just values"? I'm not sure I understand. Surely S1, S2, and S3 are
identifiers representing integer constants.


S1, S2, and S3 are not associated with regions of storage. When
you use one of them in your program, all you get is a value.
--
"When in doubt, treat ``feature'' as a pejorative.
(Think of a hundred-bladed Swiss army knife.)"
--Kernighan and Plauger, _Software Tools_
Nov 14 '05 #8
Martin wrote:
"Michael Mair" wrote:
To clarify:
Every enumerated type is distinct from every other enumerated or integer
type but is compatible to either char or a signed or unsigned integer
type. IOW: While the identifier S3 gives you a constant of type
int, the underlying enumerated type is not
necessarily int.


But I'm passing the identifier S3 to function fn(), and S3 is the identifier
of an integer constant. By all means warn me I'm passing an int to a
function expecting unsigned int, but what does " Converting enum '{...}' to
int" supposed to mean?


The thing is that *lint is sometimes too paranoid (even if your being
paranoid does not mean they are not after you).
This is such a case.

It is not clear which type the enumerated type is compatible to,
thus lint sees this as a potentially dangerous conversion -- without
considering the fact that the semantics say this never can go wrong
as all candidate types undergo the standard integer promotions.

I would just throw this special warning away. Even if we forget for
a moment that casting to shut the compiler or lint up is evil, it
is completely pointless here. Casting a return value to void may
make sense sometimes but casting a constant of type int to int does
not.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #9
On Wed, 23 Feb 2005 23:18:45 -0000, "Martin"
<martin.o_brien@[no-spam]which.net> wrote:
"Michael Mair" wrote:
To clarify:
Every enumerated type is distinct from every other enumerated or integer
type but is compatible to either char or a signed or unsigned integer
type. IOW: While the identifier S3 gives you a constant of type
int, the underlying enumerated type is not
necessarily int.


But I'm passing the identifier S3 to function fn(), and S3 is the identifier
of an integer constant. By all means warn me I'm passing an int to a
function expecting unsigned int, but what does " Converting enum '{...}' to
int" supposed to mean?


The enum value is not necessarily an int.

6.7.2.2 par 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,108) but shall be capable of representing the
values of all the members of the enumeration.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 14 '05 #10
Alan Balmer wrote:
On Wed, 23 Feb 2005 23:18:45 -0000, "Martin"
<martin.o_brien@[no-spam]which.net> wrote:

"Michael Mair" wrote:
To clarify:
Every enumerated type is distinct from every other enumerated or integer
type but is compatible to either char or a signed or unsigned integer
type. IOW: While the identifier S3 gives you a constant of type
int, the underlying enumerated type is not
necessarily int.


But I'm passing the identifier S3 to function fn(), and S3 is the identifier
of an integer constant. By all means warn me I'm passing an int to a
function expecting unsigned int, but what does " Converting enum '{...}' to
int" supposed to mean?

The enum value is not necessarily an int.

6.7.2.2 par 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,108) but shall be capable of representing the
values of all the members of the enumeration.


However, par 3 states that the identifiers give us constants
of type int.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #11
Martin wrote:
"Ben Pfaff" wrote:
Enumeration values are not objects. Objects are
regions of storage, but enumeration values are
just values.


"just values"? I'm not sure I understand. Surely S1, S2, and S3 are
identifiers representing integer constants.


In that case, why don't you try to assign a new value to them?
Christian
Nov 14 '05 #12
On Wed, 23 Feb 2005 23:18:45 -0000, Martin
<martin.o_brien@[> wrote:
"Michael Mair" wrote:
To clarify:
Every enumerated type is distinct from every other enumerated or integer
type but is compatible to either char or a signed or unsigned integer
type. IOW: While the identifier S3 gives you a constant of type
int, the underlying enumerated type is not
necessarily int.


But I'm passing the identifier S3 to function fn(), and S3 is the identifier
of an integer constant. By all means warn me I'm passing an int to a
function expecting unsigned int, but what does " Converting enum '{...}' to
int" supposed to mean?


It means that the compiler is being way over-zealous in issuing warning
(at least one of the ARM compilers is like that). Or possibly it means
that you are compiling C using a C++ compiler, where enums are a
different type from int.

I don't want warnings when converting int to unsigned int either, since
that is explicitly defined in the standard -- and would mean that saying
unsigned int fred = 1; gave a warning! It's bad enough when compilers
warn every time I convert with potential loss of precision or range
(like assigning an int to to a char), it results in loads of unnecessary
casts just to shut the compiler up.

Chris C
Nov 14 '05 #13
"Martin" <martin.o_brien@[no-spam]which.net> wrote:
"Ben Pfaff" wrote:
Enumeration values are not objects. Objects are
regions of storage, but enumeration values are
just values.
"just values"? I'm not sure I understand. Surely S1, S2, and S3 are
identifiers representing integer constants.


Integer constant _values_, yes. Not integer objects. In effect, once
you've defined that enum, S1, S2 and S3 have the same status as 3, 4.5,
or 'a'.
I think I'm surprised that the program even understands what S3 is and can
print it out, because no variable of type an_enum_t has been declared.


So? Even if I have declared no variables of type char, putchar('x') will
work. S3 has a _value_. Once you've defined an an_enum_t object, you can
give that the value of S1, S2, or S3; but no matter which value the
object has, the program still recognises all those values. How else
would you initialise an an_enum_t in the first place, if you need one to
_have_ a value to be able to use that value?
I've never been impressed with lint diagnostics. Often they
don't make a whole lot of sense in context, as you've discovered.


I do find it puzzling. I don't really understand what Lint sees as the
problem.


In all probability neither does lint.

Richard
Nov 14 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: Vu Pham | last post by:
I think this problem relates to either c or c++ ( but I am not sure which one ) so I post to both of these news group. I am sorry if I did something wrong here. Is there any difference between...
2
by: Steven T. Hatton | last post by:
typedef struct { unsigned char e_ident; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags;...
4
by: Chris | last post by:
I've lurked around long enough... Time to interract =) I'm trying to make sense of the following. I can't quite wrap my head around what this is actually doing: ------------- typedef enum {...
30
by: stephen henry | last post by:
Hi all, I have a question that I'm having difficulty answering. If I have a struct: typedef struct my_struct_tag{ struct my_other_struct *other; } my_struct_tag
5
by: Cancerbero | last post by:
Hi (first, excuse me for my bad english) As I know, the semantics for typedef is: typedef A B; I think this makes B a synonym of A, where A is an existing data type. Is that right? Based...
2
by: Mehta Shailendrakumar | last post by:
Hi all, Have alook at two different declarations below: typedef unsigned char uc; typedef void (*fptr) (void); The first declaration has a left part which is a C keyword: "unsigned char"...
8
by: Ronny Mandal | last post by:
Consider these two: Typedef struct { int foo, bar } FooBar; struct FooBar { int foo, bar }; What woul be the only difference here; just that I can create new instances by 'Foobar fb, *pfb',...
3
by: Blip | last post by:
typedef struct Ctrl_t { Int8U *pData; Int32U Counter; UsbEpStatus_t EpStatus; }Ctrl_t, *pCtrl_t; It appears that two synonyms are defined for the structure but one is a pointer? What is...
1
by: sophia | last post by:
Dear all, the following are the differences b/w #define and typedef ,which i have seen in Peter van der lindens book. is there any other difference between thes two ? The right way to...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.