is "typedef int int;" illegal????

J

jacob navia

Hi

Suppose you have somewhere

#define BOOL int

and somewhere else

typedef BOOL int;

This gives

typedef int int;

To me, this looks like a null assignment:

a = a;

Would it break something if lcc-win32 would accept that,
maybe with a warning?

Is the compiler *required* to reject that?

Microsoft MSVC: rejects it.
lcc-win32 now rejects it.
gcc (with no flags) accepts it with some warnnings.

Thanks

jacob
 
R

Robert Gamble

jacob said:
Hi

Suppose you have somewhere

#define BOOL int

and somewhere else

typedef BOOL int;

This gives

typedef int int;

The typedef name must be an identifier, here you have a keyword.
To me, this looks like a null assignment:

a = a;

Maybe from an implementor's point of view but the Standard does not
allow it.
Would it break something if lcc-win32 would accept that,
maybe with a warning?

A diagnostic would be required, after that you can do anything you
want, including continuing to compile the program as you normally
would.
Is the compiler *required* to reject that?

Define reject. You are required to produce a diagnostic, that's it.
Microsoft MSVC: rejects it.
Good.

lcc-win32 now rejects it.
Good.

gcc (with no flags) accepts it with some warnnings.

It fails to compile for me (gcc 4.0.2):
error: two or more data types in declaration specifiers

Robert Gamble
 
J

jacob navia

Robert Gamble a écrit :
The typedef name must be an identifier, here you have a keyword.




Maybe from an implementor's point of view but the Standard does not
allow it.




A diagnostic would be required, after that you can do anything you
want, including continuing to compile the program as you normally
would.

OK, that is what I had in mind.
Define reject. You are required to produce a diagnostic, that's it.

Reject means the program fails to compile. A warning is not a reject
since the program compiles.
It fails to compile for me (gcc 4.0.2):
error: two or more data types in declaration specifiers

Strange, I get the following:

[root@gateway root]# gcc -v
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/specs
gcc version 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)
[root@gateway root]# cat tint.c
typedef int int;
[root@gateway root]# gcc -c tint.c
tint.c:1: warning: useless keyword or type name in empty declaration
tint.c:1: warning: empty declaration
[root@gateway root]# ls -l tint.o
-rw-r--r-- 1 root root 703 Mar 24 16:17 tint.o
[root@gateway root]#

Program is not rejected.
 
R

Robert Gamble

jacob said:
Robert Gamble a écrit :

OK, that is what I had in mind.


Reject means the program fails to compile. A warning is not a reject
since the program compiles.

With that definition no, you are not required to reject such a program
but you are certainly free to do so.
It fails to compile for me (gcc 4.0.2):
error: two or more data types in declaration specifiers

Strange, I get the following:

[root@gateway root]# gcc -v
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/specs
gcc version 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)
[root@gateway root]# cat tint.c
typedef int int;
[root@gateway root]# gcc -c tint.c
tint.c:1: warning: useless keyword or type name in empty declaration
tint.c:1: warning: empty declaration
[root@gateway root]# ls -l tint.o
-rw-r--r-- 1 root root 703 Mar 24 16:17 tint.o
[root@gateway root]#

Program is not rejected.

Quite a bit has changed since gcc 2.96 including the strictness of the
syntax and type checking. Note though that a diagnostic was still
produced.

Robert Gamble
 
J

James Dennett

jacob said:
Robert Gamble a écrit :

OK, that is what I had in mind.


Reject means the program fails to compile. A warning is not a reject
since the program compiles.

The standard doesn't ever require a compiler to reject
code; it's quite legal for a C compiler to accept Fortran
code, so long as it prints out a diagnostic (maybe
"This looks like Fortran, not C... compiling it anyway...").

There is a common notion among compilers that a "warning" is
a non-fatal diagnostic and an "error" is a fatal diagnostic
(i.e., one which causes no object code to be produced), but
that is not standardised.
It fails to compile for me (gcc 4.0.2):
error: two or more data types in declaration specifiers

Strange, I get the following:

[root@gateway root]# gcc -v
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/specs
gcc version 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)
[root@gateway root]# cat tint.c
typedef int int;
[root@gateway root]# gcc -c tint.c
tint.c:1: warning: useless keyword or type name in empty declaration
tint.c:1: warning: empty declaration
[root@gateway root]# ls -l tint.o
-rw-r--r-- 1 root root 703 Mar 24 16:17 tint.o
[root@gateway root]#

Program is not rejected.

That's a nearly 6-year old compiler, and not an official GCC
release at that. Not to say that 2.96 didn't have its uses,
and maybe it still does, but it's far from the state of the
art.

-- James
 
D

David R Tribble

Robert said:
Maybe from an implementor's point of view but the Standard does not
allow it.
The typedef name must be an identifier, here you have a keyword.

Exactly.

On a related note, I've suggested in the past that duplicate
(redundant) typedefs be allowed as long as they are semantically
equivalent, e.g.:

typedef long mytype; // A
typedef long mytype; // B, error in C99
typedef long int mytype; // C, error in C99

It would introduce no problems if the redundant typedefs at B and C
were allowed. C99 rules, however, disallow this, so we're forced to
do things like the following in all our header files:

// foo.h
#ifndef MYTYPE_DEF
typedef long mytype;
#define MYTYPE_DEF
#endif

// bar.h
#ifndef MYTYPE_DEF
typedef long int mytype;
#define MYTYPE_DEF
#endif


Allowing redundant typedefs parallels the rule allowing redundant
preprocessor macro definitions:

#define SIZE 100 // D
#define SIZE 100 // E, okay, duplicate allowed

This also parallels C++ semantics, which allow duplicate typedefs.

-drt
 
J

jacob navia

James Dennett a écrit :
Strange, I get the following:

[root@gateway root]# gcc -v
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/specs
gcc version 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)
[root@gateway root]# cat tint.c
typedef int int;
[root@gateway root]# gcc -c tint.c
tint.c:1: warning: useless keyword or type name in empty declaration
tint.c:1: warning: empty declaration
[root@gateway root]# ls -l tint.o
-rw-r--r-- 1 root root 703 Mar 24 16:17 tint.o
[root@gateway root]#

Program is not rejected.


That's a nearly 6-year old compiler, and not an official GCC
release at that. Not to say that 2.96 didn't have its uses,
and maybe it still does, but it's far from the state of the
art.

-- James

Wow, this complicates this quite a bit.
If Microsoft AND gcc reject the code... I think better leave it as it is...
I thought that gcc let it pass with some warnings and intended to do the
same, but it is true that I have not upgraded gcc since quite a while.

thanks
 
D

Douglas A. Gwyn

jacob said:
#define BOOL int
typedef BOOL int;
Would it break something if lcc-win32 would accept that,
maybe with a warning?

Please don't try to change the language, it doesn't do your
users any favor. Indeed, it merely encourages even more
out-of-control coding
Is the compiler *required* to reject that?

A diagnostic is required.
 
E

Eric Sosman

David R Tribble wrote On 03/24/06 11:01,:
On a related note, I've suggested in the past that duplicate
(redundant) typedefs be allowed as long as they are semantically
equivalent, e.g.:

typedef long mytype; // A
typedef long mytype; // B, error in C99
typedef long int mytype; // C, error in C99

It seems to me "semantically equivalent" might
open an unpleasant can of worms. For example, are

typedef unsigned int mytype;
typedef size_t mytype;

"semantically equivalent" on an implementation that
uses `typedef unsigned int size_t;'? What's really
wanted is "equivalence of intent," which seems a
harder notion to pin down.

If the suggestion were modified to require "lexical
equivalence," such questions would disappear and I don't
think the language would be any the worse without them.
Writing header files would perhaps not be quite as much
easier as with "semantic equivalence," but I think would
be a good deal easier than it is now.
 
W

Wojtek Lerch

Eric Sosman said:
David R Tribble wrote On 03/24/06 11:01,:

It seems to me "semantically equivalent" might
open an unpleasant can of worms. For example, are

typedef unsigned int mytype;
typedef size_t mytype;

"semantically equivalent" on an implementation that
uses `typedef unsigned int size_t;'? What's really
wanted is "equivalence of intent," which seems a
harder notion to pin down.

Couldn't it simply use the same rules as declarations do -- i.e. require
compatible types?

extern unsigned int myvar;
extern size_t myvar;
 
J

jacob navia

Douglas A. Gwyn a écrit :
Please don't try to change the language, it doesn't do your
users any favor. Indeed, it merely encourages even more
out-of-control coding




A diagnostic is required.

Well, "changing the language" is quite an overkill. Gcc 2.xx accepted
that (with warnings). Did they "change the language" ???

But basically why

typedef int int;

should be forbidden? Like

a = a;

it does nothing and the language is not changed, at most is made more
consistent.

But since gcc has changed its behavior in later versions, as I learned
in this forum, and microsoft rejects it, I think I will not do this.

Thanks for your reply
 
W

Wojtek Lerch

loufoque said:
jacob navia wrote :



Defining a type that already exists makes no sense.

But *declaring* something that's already been declared is generally OK
in C. Why does a typedef have to behave like a definition rather than a
declaration -- it doesn't reserve any storage, just binds a type to an
identifier.

(The idea of allowing a keyword for a typedef name is a different story;
personally, I don't like it.)
 
E

Eric Sosman

Wojtek Lerch wrote On 03/24/06 12:25,:
Couldn't it simply use the same rules as declarations do -- i.e. require
compatible types?

extern unsigned int myvar;
extern size_t myvar;

Yes it could, and since `typedef' doesn't actually
define types (it just defines aliases) the issue could
be resolved this way. But is that the way we *want* it
resolved, from a portability perspective? It would open
the door (or fail to close the door) to bletcherous
abuses like `typedef time_t ptrdiff_t', things that would
work on some platforms but go horribly wrong on others.

We've got time_t and size_t and int16_t and all the
rest specifically so the programmer has a chance to stay
above the implementation-specific fray. It would seem a
step in the wrong direction to make typedef weaker than
it already is.

(Isn't there a "what if" rule somewhere? ;-)
 
M

Mark McIntyre

Well, "changing the language" is quite an overkill. Gcc 2.xx accepted
that (with warnings).

A warning is a diagnostic.
Did they "change the language" ???

They emitted a diagnostic.
But basically why

typedef int int;

its meaningless.
should be forbidden? Like

a = a;

it has a meaning, albeit a pointless one.

You might as well say
"why is it incorrect to say 'runned bluer which apple' but ok to say
'prunes are orange' ?"



Mark McIntyre
 
W

Wojtek Lerch

Eric Sosman said:
Wojtek Lerch wrote On 03/24/06 12:25,:

Yes it could, and since `typedef' doesn't actually
define types (it just defines aliases) the issue could
be resolved this way. But is that the way we *want* it
resolved, from a portability perspective? It would open
the door (or fail to close the door) to bletcherous
abuses like `typedef time_t ptrdiff_t', things that would
work on some platforms but go horribly wrong on others.

They wouldn't go horribly wrong, just cause a compile error, like they now
do on all platforms. They would behave the same way as this:

time_t fun();
ptrdiff_t fun();

or this:

time_t var;
ptrdiff_t *ptr = &var;

I'd expect these to be more likely to appear in a program by mistake than
your "typedef time_t ptrdiff_t" -- are you more worried about abuses that
are so obviously bletcherous that no sane person would put them in their
code?
We've got time_t and size_t and int16_t and all the
rest specifically so the programmer has a chance to stay
above the implementation-specific fray. It would seem a
step in the wrong direction to make typedef weaker than
it already is.

In the existing C (and, presumably, in the proposed "C with redundant
typedefs"), trying to redefine a *standard* typedef in a program is
undefined behaviour anyway (7.1.3p2). And so is trying to declare a
standard function after including the corresponding header. Nevertheless, C
allows programs to declare the same function twice; do you think that should
be forbidden, too?
 
J

jacob navia

Wojtek Lerch a écrit :
In the existing C (and, presumably, in the proposed "C with redundant
typedefs"), trying to redefine a *standard* typedef in a program is
undefined behaviour anyway (7.1.3p2). And so is trying to declare a
standard function after including the corresponding header. Nevertheless, C
allows programs to declare the same function twice; do you think that should
be forbidden, too?

VERY GOOD POINT!
 
K

kuyper

James Dennett wrote:
....
The standard doesn't ever require a compiler to reject
code;

Not quite: section 3.17p4 says :

"The implementation shall not successfully translate a preprocessing
translation unit containing a #error preprocessing directive unless it
is part of a group skipped by conditional inclusion."

However, that is the only exception to your statement.
 
J

Jordan Abel

Robert Gamble a écrit :

OK, that is what I had in mind.


Reject means the program fails to compile. A warning is not a reject
since the program compiles.

There is absolutely nothing that the standard requires to fail to
compile, with the SOLE exception of a program containing the #error
directive.
 
J

Jordan Abel

Douglas A. Gwyn a écrit :

Well, "changing the language" is quite an overkill. Gcc 2.xx accepted
that (with warnings). Did they "change the language" ???

GCC also didn't do what you think it did with it. It interpreted it as
"define (nothing) to be 'int int'", _NOT_ "define int to be int".

And a warning _does_ satisfy the requirement for a diagnostic.
 

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,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top