typedef foo int;
typedef foo int;
is it an error, but when I say:
typedef size_t int;
typedef size_t int;
I get only a warning?
Is it because size_t (and perhaps others) are a special case to avoid
#include nightmares? Or when size_t is defined is it done in a special
way?
Thanks,
Greg
--
comp.lang.c.moderated - moderation address: cl...@plethora.net
> Why when I say
>
> typedef foo int;
> typedef foo int;
>
> is it an error, but when I say:
>
> typedef size_t int;
> typedef size_t int;
>
> I get only a warning?
>
> Is it because size_t (and perhaps others) are a special case to avoid
> #include nightmares? Or when size_t is defined is it done in a special
> way?
I would say there are multiple problems here.
First, with the examples below, even the first typedef in each set is
illegal; you're trying to redefine _int_ which is flat-out illegal.
Presuming you meant to define foo and size_t (respectively) as int and
not the other way around, _and_ that you've included <stddef.h> or
<stdio.h>, the first of the size_t typedefs is almost certainly illegal,
since that is probably not how size_t is defined on your system. The
first typedef for size_t should be _illegal_. My recollection is that
multiple typedefs are legal provided they are identical; multiple
incompatible typedefs are illegal, however.
I would say user/compiler weirdness is going on here; you haven't said
which compiler you're using, either, and they all do things slightly
differently.
--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ Too much agreement kills a chat.
\__/ Eldridge Cleaver
Alcyone Systems' CatCam / http://www.catcam.com/
What do your pets do all day while you're at work? Find out.
int is a keyword, and in both situations you are attempting to make
is an alias for some other type. That's an error in both cases.
I could guess what you mean, but it's best to just say that you
should recheck your example and repost your questions.
--
Greg Comeau Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==> http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo! NEW: Try out our C99 mode!
com...@comeaucomputing.com http://www.comeaucomputing.com
[ ... snippage ...]
>
> I would say there are multiple problems here.
>
> First, with the examples below, even the first typedef in each set is
> illegal; you're trying to redefine _int_ which is flat-out illegal.
>
> Presuming you meant to define foo and size_t (respectively) as int and
> not the other way around, _and_ that you've included <stddef.h> or
> <stdio.h>,
DOH! Sorry -- you are of course absolutely right, I meant to say
"typedef int foo" and "typedef int size_t"
I had some ideas for further investigation. Gcc compiles
#include <stddef.h>
typedef unsigned int size_t;
typedef unsigned int size_t;
with a warning that I'm redefining size_t, but if I loose the #include
then it gives an error. This would imply that stddef.h is doing some
magic that tells the compiler "allow redefinition of this typedef"
(attribute/pragma or some such). However, examination of stddef shows
nothing of the sort.
So I tried changing the program to
# 1 "stddef.h" 3
# 1 "foo.c"
typedef unsigned int size_t;
typedef unsigned int size_t;
and it compiles with warnings. If I then remove the first line, it
gives an error.
So if appears that gcc has some horrible hack to see if it looks as
though stddef has been included, and if so allow redefiniton of standard
types.. yuk!!
Greg
typedef int foo; // foo now means int
typedef int foo; // NO, attempting typedef int int
typedef foo bar; // bar now also means int
This form of "type definition" establishes a synonym for an
existing type; it doesn't create a new type, nor is it the
same as simple macro substitution.
Such a facility *could* have been designed differently,
but historically this is how it works.
The standard workaround is something like:
#ifndef foo_DEFINED
typedef int foo;
#define foo_DEFINED
#endif
If you look at enough implementations of system headers on
current platforms you will see a lot of this kind of thing,
because some standard typedef names are defined by whichever
of several headers is #included first, and the other headers
that *might* have provided the definition must then *not*
try to define the typedef name.
If one were designing a new C-like language, presumably this
is one feature that should be improved.
Probably. In any event, the duplicate typedef is ok in C++,
and an error in C90 and C99.
--
Greg Comeau Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==> http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo! NEW: Try out our C99 mode!
com...@comeaucomputing.com http://www.comeaucomputing.com
# 1 "stddef.h" 3
# 1 "foo.c"
typedef unsigned int size_t;
typedef unsigned int size_t;
This is the .c file *in its entirity*. If compiles with gcc, even with
ansi and pedantic flags set (although with a few) warnings.
Interesting, if I change the #line directives, even slightly, it stops
working!
Greg
Well, I got a dianostic from gcc on the above (albeit a warning
for the duplicate typedef, but I'm sure there's an option where
it will produce an error). Also, Comeau C++ in C modes will also
produce an error in strict mode.
--
Greg Comeau Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==> http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo! NEW: Try out our C99 mode!
com...@comeaucomputing.com http://www.comeaucomputing.com
Sure, I get a warning too. But my point is that
# 1 "stddef.h" 3
# 1 "foo.c"
typedef unsigned int size_t;
typedef unsigned int size_t;
gives a *warning*, but
# 1 "foo.c"
typedef unsigned int size_t;
typedef unsigned int size_t;
gives an *error*.
I am surprised that # line directives modify behaviour like this!
Greg
$ cc -c foo.c # native mode for Forte C
"foo.c", line 1: warning: tokens ignored at end of directive line
"foo.c", line 2: warning: typedef redeclared: size_t
$ cc -c -Xc foo.c # strict conformance mode for Forte C
"foo.c", line 1: warning: interpreted as a #line directive
"foo.c", line 1: warning: directive is an upward-compatible ANSI C
extension
"foo.c", line 1: warning: tokens ignored at end of directive line
"stddef.h", line 1: warning: interpreted as a #line directive
"stddef.h", line 1: warning: directive is an upward-compatible ANSI C
extension
"foo.c", line 2: warning: typedef redeclared: size_t
So, it doesn't "work", although this particular compiler goes ahead
and generates code in accordance to what you seem to expect. Other
compilers can (and some do) fail to translate the source at all.
That's funny; for me, the following compiles with warnings:
straum% cat foo.c
typedef unsigned int size_t;
typedef unsigned int size_t;
straum% cc -c foo.c
foo.c:2: redefinition of `size_t'
foo.c:1: `size_t' previously declared here
straum% cc -v
Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.4/specs
gcc version 2.95.4 20010506 (Debian prerelease)
I don't need any "#line" indicators. Could you provide a similar
transcript demonstrating your claim -- that your version works, and
that a modified version does not, and what version of gcc you're using?
(I'm using Debian unstable, btw, with Linux kernel version 2.4.4 and
glibc 2.2.3.)
-andy
I apologize, I made a stupid mistake here. gcc does, in fact, behave
differently in the presence of #line directives; it apparently does so
to facilitate users' working around broken system header files
(the relevant predicate is DECL_IN_SYSTEM_HEADER). That magic number
at the end of the line ("3" below) indicates what kind of file is at
hand. 3 apparently indicates that the header file in question is a
system header file. The filename (the string in quotes) can be changed
at will, so long as the 3 remains intact.
Here's the transcript (same system as last time):
straum% cat foo.c
# 1 "bar.h" 3
typedef unsigned int size_t;
typedef unsigned int size_t;
size_t c;
straum% gcc -c foo.c
bar.h:2: warning: redefinition of `size_t'
bar.h:1: warning: `size_t' previously declared here
straum% cat bar.c
# 1 "bar.h" 1
typedef unsigned int size_t;
typedef unsigned int size_t;
size_t c;
straum% gcc -c bar.c
In file included from bar.c:1:
bar.h:2: redefinition of `size_t'
bar.h:1: `size_t' previously declared here
The latter file results in an error, while the prior is just a warning.
(You'll also notice how the "#line" directives mess up the error
report strings, which is to be expected.)
As the original poster said, this is suprising behavior on gcc's part.
> I am surprised that # line directives modify behaviour like this!
In the Info node (cpp)Output:
`3'
This indicates that the following text comes from a system header
file, so certain warnings should be suppressed.
That's exactly what behaviour I get -- the above compilation produced an
*error* on line 2. i.e.
glaw@glaw-pc:/tmp$ cat > foo.c
typedef int size_t;
typedef int size_t;
glaw@glaw-pc:/tmp$ gcc -c foo.c
foo.c:2: redefinition of `size_t'
foo.c:1: `size_t' previously declared here
glaw@glaw-pc:/tmp$ ls -l foo.o
ls: foo.o: No such file or directory
However, if I put # line directives, I get warnings instead of errors:
glaw@glaw-pc:/tmp$ cat > foo.c
# 1 "stddef.h" 3
# 1 "foo.c"
typedef int size_t;
typedef int size_t;
glaw@glaw-pc:/tmp$ gcc -c foo.c
foo.c:2: warning: redefinition of `size_t'
foo.c:1: warning: `size_t' previously declared here
glaw@glaw-pc:/tmp$ ls -l foo.o
-rw-r--r-- 1 glaw glaw 690 May 22 10:54 foo.o
Greg