GCC: non-conforming implementation of C++

B

borophyll

GCC allows you to define macros called "new" and "delete" in the
preprocessor phase. This seems to be in violation of the C++ spec, in
particular the rules for the creation of preprocessing tokens.
Section 2.4 of ISO/IEC 14882:2003 states that preprocessing tokens
belong to one of the following groups

preprocessing-token:
header-name
identifier
pp-number
character-literal
string-literal
preprocessing-op-or-punc
each non-white-space character that cannot be one of the
above

Section 2.12 defines a preprocessing-op-or-punc to be:

preprocessing-op-or-punc: one of
{ } [ ] # ## ( )
<: :> <% %> %: %:%: ; : ...
new delete ? :: . .*
+ - * / % ˆ & | ̃
! = < > += -= *= /= %=
ˆ= &= |= << >> >>= <<= == !=
<= >= && || ++ -- , ->* ->
and and_eq bitand bitor compl not not_eq
or or_eq xor xor_eq

Since "new" and "delete" are preprocessing-op-or-punc's, does this not
violate the spec?

Regards
B.
 
G

goodmen

MS vc also allow new delete be defined as macro.

in fact, MFC take use of this.

2years ago, i use mfc in my project, and found
it generate many many compile error.
Finally, I found that MFC define keyword new at the
begin of the cpp file. and i #include STL headers
behind the that definition, so the compiler is angry.

I copy/paste the stl header include before the
define, all is ok.

That is my story, don't laugh at me...............
 
J

JohnQ

"GCC allows you to define macros called "new" and "delete" in the
preprocessor phase."

That's interesting. Can some please post those macro definitions here?

John
 
B

borophyll

"GCC allows you to define macros called "new" and "delete" in the
preprocessor phase."

That's interesting. Can some please post those macro definitions here?


This code compiles in GCC.

#include <stdio.h>
#define new 1
#define delete 2
int main()
{

printf("%d\n", new + delete);
return 0;
}

While this is a simple example, new and delete can be defined to be
any macro.
 
J

Jack Klein

GCC allows you to define macros called "new" and "delete" in the
preprocessor phase. This seems to be in violation of the C++ spec, in
particular the rules for the creation of preprocessing tokens.
Section 2.4 of ISO/IEC 14882:2003 states that preprocessing tokens
belong to one of the following groups

[snip]

Paragraph 2 of 17.4.3.1.1 Macro names forbids definition of keywords
as macros (note that new and delete are keywords). Attempting to do
so makes the program ill-formed and the behavior undefined. So the
compiler is free to do what it likes.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
B

borophyll

Paragraph 2 of 17.4.3.1.1 Macro names forbids definition of keywords
as macros (note that new and delete are keywords). Attempting to do
so makes the program ill-formed and the behavior undefined. So the
compiler is free to do what it likes.

Hi Jack

Thanks for the reply. I am having difficulty understanding the
relevant portion of the spec you are referring to. I think this is
the portion that you draw the above from:

"Each name defined as a macro in a header is reserved to the
implementation for any use if the translation unit includes the
header.

A translation unit that includes a header shall not contain any macros
that define names declared or defined in that header. Nor shall such a
translation unit define macros for names lexically identical to
keywords."

Correct me if I'm wrong, but doesn't this only cover the case of a
source file which includes a header? What if the file does not
include a header?
 
B

Bo Persson

(e-mail address removed) wrote:
::
:::
::: Paragraph 2 of 17.4.3.1.1 Macro names forbids definition of
::: keywords as macros (note that new and delete are keywords).
::: Attempting to do so makes the program ill-formed and the behavior
::: undefined. So the compiler is free to do what it likes.
:::
::
:: Hi Jack
::
:: Thanks for the reply. I am having difficulty understanding the
:: relevant portion of the spec you are referring to. I think this is
:: the portion that you draw the above from:
::
:: "Each name defined as a macro in a header is reserved to the
:: implementation for any use if the translation unit includes the
:: header.
::
:: A translation unit that includes a header shall not contain any
:: macros that define names declared or defined in that header. Nor
:: shall such a translation unit define macros for names lexically
:: identical to keywords."
::
:: Correct me if I'm wrong, but doesn't this only cover the case of a
:: source file which includes a header? What if the file does not
:: include a header?

Yes, this is considered a bug in the standard document. :)

For the next edition of the standard, this section has been rephrased
as:

A translation unit that includes a standard library header shall not
#define or #undef names declared in any standard library header.

A translation unit shall not #define or #undef names lexically
identical to keywords.


http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#294



Bo Persson
 
K

Kai-Uwe Bux

Jack said:
GCC allows you to define macros called "new" and "delete" in the
preprocessor phase. This seems to be in violation of the C++ spec, in
particular the rules for the creation of preprocessing tokens.
Section 2.4 of ISO/IEC 14882:2003 states that preprocessing tokens
belong to one of the following groups

[snip]

Paragraph 2 of 17.4.3.1.1 Macro names forbids definition of keywords
as macros (note that new and delete are keywords). Attempting to do
so makes the program ill-formed

So far, I am with you.
and the behavior undefined. So the compiler is free to do what it likes.

That, I don't see. The paragraph reads:

A translation unit that includes a header shall not contain any macros
that define names declared or defined in that header. Nor shall such a
translation unit define macros for names lexically identical to keywords.

It looks like a diagnosable rule to me for which a diagnostic would be
required by [1.4/1]. After that diagnostic, the compiler is free to go
ahead an translate the code anyway.


Best

Kai-Uwe Bux
 
M

MQ

Yes, this is considered a bug in the standard document. :)

For the next edition of the standard, this section has been rephrased
as:

A translation unit that includes a standard library header shall not
#define or #undef names declared in any standard library header.

A translation unit shall not #define or #undef names lexically
identical to keywords.

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#294

Bo Persson

Thanks for the link. As the implementor of a compiler, should I make
this an error, forcing termination of compilation? For interest's
sake, is there any real concern with compatibility with old code if I
did this?

Regards
B.
 
B

Bo Persson

MQ wrote:
::
::: Yes, this is considered a bug in the standard document. :)
:::
::: For the next edition of the standard, this section has been
::: rephrased as:
:::
::: A translation unit that includes a standard library header shall
::: not #define or #undef names declared in any standard library
::: header.
:::
::: A translation unit shall not #define or #undef names lexically
::: identical to keywords.
:::
::: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#294
:::
::: Bo Persson
::
:: Thanks for the link. As the implementor of a compiler, should I
:: make this an error, forcing termination of compilation? For
:: interest's sake, is there any real concern with compatibility with
:: old code if I did this?
::

Depending on your audience, you should probably consider having this
selectable at compile time. Older *very popular* compilers, like MS
VC6, did strange things like

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

which was technically sort of ok at the time, as the compiler appeared
before the first C++ standard.

There are TONS of old code around, some of which you cannot change
whatever you do. A very popular OS is installed in 100s of millions of
copies, using pre-standard data types.

If you try to sell your compiler, you first have to decide if it
should accept this code:


#include "windows.h"

int main()
{ }


Your choice! :)



Bo Persson
 
J

James Kanze

On Jul 28, 1:25 am, "JohnQ" <[email protected]>
wrote:
This code compiles in GCC.
#include <stdio.h>
#define new 1
#define delete 2
int main()
{
printf("%d\n", new + delete);
return 0;
}

This happens to be a perfectly legal C program, so any C
compiler should compile it (and I doubt you'll find any that
don't). I imagine most C++ compilers will compile it as well,
simply because they tend to be compatible with C for this sort
of thing. Redefining a keyword by means of a macro is undefined
behavior if you include any C++ header, however (and <stdio.h>
is a C++ header, albeit a deprectated one, in a C++ program).
That doesn't mean it won't compile and run; it just means that
you have no idea what it might do.
 
O

Old Wolf

GCC allows you to define macros called "new" and "delete" in the
preprocessor phase. This seems to be in violation of the C++ spec

The spec only says that such a program isn't a
valid C++ program. It doesn't mandate that a
compiler can't compile it anyway.
 
J

James Kanze

GCC allows you to define macros called "new" and "delete" in the
preprocessor phase. This seems to be in violation of the C++ spec, in
particular the rules for the creation of preprocessing tokens.
Section 2.4 of ISO/IEC 14882:2003 states that preprocessing tokens
belong to one of the following groups

Paragraph 2 of 17.4.3.1.1 Macro names forbids definition of keywords
as macros (note that new and delete are keywords). Attempting to do
so makes the program ill-formed and the behavior undefined. So the
compiler is free to do what it likes.

I think you're missing his point; I missed it too in an earlier
posting. The point is that according to §2.12, new and delete
are *not* keywords; they are preprocessing-op-or-punc. G++ does
complain if you try something like:
#define or &&
(or is also a preprocessing-op-or-punc).

Of course, the standard (apparently at least) contradicts itself
here, since in §2.11, it says that they are keywords (where as
or et al. explicitly aren't, but form another category:
alternate representations).

I rather think that it's an error that new and delete appear as
preprocessing-op-or-punc. They're listed as keywords as well
(and they aren't the only keywords which can be operators---the
new style casts involve a keyword as well, as does typeid).
I'll post a defect report in comp.std.c++.
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top