Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

redefinition of typedef size_t

996 views
Skip to first unread message

Greg Law

unread,
May 16, 2001, 11:52:51 AM5/16/01
to
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?

Thanks,

Greg
--
comp.lang.c.moderated - moderation address: cl...@plethora.net

Erik Max Francis

unread,
May 16, 2001, 8:06:50 PM5/16/01
to
Greg Law wrote:

> 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.

Greg Comeau

unread,
May 16, 2001, 8:29:08 PM5/16/01
to
In article <clcm-2001...@plethora.net>,

Greg Law <gl...@nexwave-solutions.com> wrote:
>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?

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

Greg Law

unread,
May 17, 2001, 1:00:13 PM5/17/01
to
Erik Max Francis wrote:
>
> Greg Law wrote:
>
> > Why when I say
> >
> > typedef foo int;

[ ... 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

Douglas A. Gwyn

unread,
May 17, 2001, 11:33:23 PM5/17/01
to
The problem, independently of GCC and trickery, is:

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.

Greg Comeau

unread,
May 17, 2001, 11:33:28 PM5/17/01
to
>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...

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

Greg Law

unread,
May 19, 2001, 11:35:11 AM5/19/01
to
"Douglas A. Gwyn" wrote:
>
> The problem, independently of GCC and trickery, is:
>
> typedef int foo; // foo now means int
> typedef int foo; // NO, attempting typedef int int
> typedef foo bar; // bar now also means int
>
I understand that, but the following program works:

# 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

Greg Comeau

unread,
May 20, 2001, 12:48:22 AM5/20/01
to
>"Douglas A. Gwyn" wrote:
>> The problem, independently of GCC and trickery, is:
>> typedef int foo; // foo now means int
>> typedef int foo; // NO, attempting typedef int int
>> typedef foo bar; // bar now also means int
>I understand that, but the following program works:
>
># 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!

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

Greg Law

unread,
May 21, 2001, 2:43:38 PM5/21/01
to
Greg Comeau wrote:
...

> 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).

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

Douglas A. Gwyn

unread,
May 21, 2001, 2:43:52 PM5/21/01
to
Greg Law wrote:
> "Douglas A. Gwyn" wrote:
> > The problem, independently of GCC and trickery, is:
> > typedef int foo; // foo now means int
> > typedef int foo; // NO, attempting typedef int int
> > typedef foo bar; // bar now also means int
> I understand that, but the following program works:
> # 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!

$ 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.

Andy Isaacson

unread,
May 21, 2001, 2:44:04 PM5/21/01
to
>I understand that, but the following program works:
>
># 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!

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

Andy Isaacson

unread,
May 22, 2001, 10:10:36 PM5/22/01
to
In article <clcm-2001...@plethora.net>,

Andy Isaacson <a...@pirx.hexapodia.org> wrote:
>That's funny; for me, the following compiles with warnings:

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.

Kalle Olavi Niemitalo

unread,
May 22, 2001, 10:10:40 PM5/22/01
to
Greg Law <gl...@nexwave-solutions.com> writes:

> 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.

Greg Law

unread,
May 22, 2001, 10:10:45 PM5/22/01
to
Andy Isaacson wrote:
>
> In article <clcm-2001...@plethora.net>,
> Greg Law <gl...@nexwave-solutions.com> wrote:
> >I understand that, but the following program works:
> >
> ># 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!
>
> 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

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

0 new messages