Topic: Defect report: [lex.key] and [lex.operators] contradict each other
Author: James Kanze <james.kanze@gmail.com>
Date: Mon, 6 Aug 2007 09:25:03 CST Raw View
On Aug 6, 1:17 am, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
> James Kanze ha scritto:
> >> int main(){
> >> void * memory = operator new(1000);
> >> mytype* = new mytype;
> >> }
> >> It is worth noting that many of the suggested preprocessor
> >> substitutions seem to assume that the programmer only uses the
> >> second case.
> > And also that he doesn't use any placement new.
> In fact there is a technique that I used a couple of times to replace
> new, that works for placement new also:
> #define new SetDebugInfo(__FILE__, __LINE__) ? 0 : new
> Sure, it doesn't work in every context where you can use "new", but it
> never failed me in real-life code.
Not even in multi-threaded code:-)?
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Tue, 31 Jul 2007 09:19:07 CST Raw View
[lex.key] and [lex.operators] give contradictory information as
to the status of new and delete: in [lex.key], they are
keywords, but in [lex.operators], they are listed as
preprocessing-op-or-punc. This affects the legality of programs
such as:
#define new 0
int
main()
{
return new ;
}
If new is a keyword, the above is a legal C++ program; if new is
a preprocessing-op-or-punc, it is not.
FWIW: g++ treats new as a keyword, which seems like the more
reasonable solution (not that it really matters which way we
choose). Following this, I would recommend simply removing new
and delete from the list of preprocessing-op-or-punc in
[lex.operators]. (Note that other keywords, such as the new
style casts or typeid, are operators, but don't appear in this
table, they don't become operators until phase 7 of translation.
I seems reasonable to me to treat new and delete like this as
well---I can't quite see anything the preprocessor will do with
them.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Tue, 31 Jul 2007 15:31:06 CST Raw View
On Jul 31, 7:32 pm, jdenn...@acm.org (James Dennett) wrote:
> James Kanze wrote:
> > [lex.key] and [lex.operators] give contradictory information as
> > to the status of new and delete: in [lex.key], they are
> > keywords, but in [lex.operators], they are listed as
> > preprocessing-op-or-punc. This affects the legality of programs
> > such as:
> > #define new 0
> > int
> > main()
> > {
> > return new ;
> > }
> > If new is a keyword, the above is a legal C++ program; if new is
> > a preprocessing-op-or-punc, it is not.
> When it comes to specifying types of tokens, I find the
> standard to be very flawed; this is the tip of the iceberg.
> There are, in some sense, two categories of token types
> in C++: one for preprocessing tokens, and one for "proper"
> tokens, with a conversion from pptokens to tokens at the
> end of preprocessing.
> Keywords are meaningless to the preprocessor; so far as
> it is concerned they are just identifiers. (I believe
> James Kanze knows this.)
Sort of. What's the "define" in #define, however, if it isn't a
keyword? Or the "defined" operator? Although I'd be hard put
to find anywhere in the standard where it says as much, I'd say
that the preprocessor has its own set of keywords, distinct from
those of C++. And unlike C++, it handles them in a context
sensitive manner: I think something like:
#define define 3
is perfectly legal, as is:
#if define == 3
. (And then people wonder why we don't like the
pre-processor:-).)
> pp-op-or-punc tokens, however,
> aren't identifiers, even if they look like them, which
> is the crux of the example above.
Exactly.
> My own interpretation of the standard was that during
> preprocessing "new" is pp-op-or-punc (as keywords aren't
> relevant), so the program above is ill-formed, and gives
> a diagnostic
> Error: Error at file {standard input}, line 1: #define directive
> followed by token 'new' of type pp_op_or_punc. #define must be
> followed by an identifier (as per 16/1)
IMHO, that's very clearly what [lex.operators] is saying. The
problem is that [lex.key] is saying exactly the opposite, almost
as clearly.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Thu, 2 Aug 2007 13:56:36 CST Raw View
On Aug 1, 6:36 am, Greg Herlihy <gre...@pacbell.net> wrote:
> On 7/31/07 8:19 AM, in article
> 1185873775.132554.287...@l70g2000hse.googlegroups.com, "James Kanze"
> <james.ka...@gmail.com> wrote:
> > [lex.key] and [lex.operators] give contradictory information as
> > to the status of new and delete: in [lex.key], they are
> > keywords, but in [lex.operators], they are listed as
> > preprocessing-op-or-punc. This affects the legality of programs
> > such as:
> > #define new 0
> > int
> > main()
> > {
> > return new ;
> > }
> > If new is a keyword, the above is a legal C++ program; if new is
> > a preprocessing-op-or-punc, it is not.
[...]
> So whether the preprocessor treats "new" as an identifier or
> as an operator depends upon the stage of preprocessing that
> the preprocessor has reached - when the "new" token is
> encountered. In stages 1-6, a "new" token is an identifier -
> but during stage 7, the preprocessor recognizes "new" as an
> operator and replaces it with a suitable operator token
> (whatever that might be).
I suspect that that's how a lot of compilers treat it. Just
like they do for the unambiguous cases, like const_cast or
typeid (which are not listed as preprocessor operators). It
also makes sense. But it's not what the standard says in
[lex.operators]. There, new and delete are listed as
preprocessor operators; i.e. tokens that are recognized by the
compiler as operators in the preprocessor stage, and thus can't
be redefined. (Something like "#define or 0" causes an error in
g++. As it should.)
It's clearly a defect in the standard. As James Dennett says,
it's really just the tip of the iceberg; there are a lot of
problems in the preprocessor and tokenization. But it would be
very, very simple to fix this one defect; just drop new and
delete from the list of preprocessor tokens, and the standard
will require the behavior that you describe (and that g++
implements).
Alternatively, one could remove new and delete from the list of
keywords, and specify that they are unambiguously a preprocessor
operator or punctuation. But for the life of me, I can't figure
out what the preprocessor is going to do with such an operator,
and all of the other preprocessor operators or punctuation which
have the syntax of an indentifier are alternate tokens;
replacements for some other token which doesn't look like an
identifier.
Note too that the preprocessor does have to deal with some
C++ keywords, e.g. true and false. But the standard is very
clear about these; they are only considered after macro
expansion, and something like:
#define true 0
is perfectly legal (just please don't do it in a program I have
to maintain).
(If someone wanted to ban defining keywords as macros entirely,
I'd be all in favor as well. But that's another issue, and a
definite change.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Pete Becker <pete@versatilecoding.com>
Date: Thu, 2 Aug 2007 17:46:53 CST Raw View
On 2007-08-02 17:19:40 -0400, AlbertoBarbati@libero.it (Alberto Ganesh
Barbati) said:
> James Kanze ha scritto:
>>
>> (If someone wanted to ban defining keywords as macros entirely,
>> I'd be all in favor as well. But that's another issue, and a
>> definite change.)
>>
>
> As a matter of fact, the standard already does it in [macro.names],
> paragraph 2: "A translation unit shall not #define or #undef names
> lexically identical to keywords."
That's from the draft of the next revision of the standard. It's not in
the current standard.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Sat, 4 Aug 2007 19:44:04 CST Raw View
On Aug 3, 5:37 pm, Francis Glassborow
<francis.glassbo...@btinternet.com> wrote:
> >> <james.ka...@gmail.com> wrote:
> >>> [lex.key] and [lex.operators] give contradictory information as
> >>> to the status of new and delete: in [lex.key], they are
> >>> keywords, but in [lex.operators], they are listed as
> >>> preprocessing-op-or-punc. This affects the legality of programs
> >>> such as:
> >>> #define new 0
> >>> int
> >>> main()
> >>> {
> >>> return new ;
> >>> }
> >>> If new is a keyword, the above is a legal C++ program; if new is
> >>> a preprocessing-op-or-punc, it is not.
> It has just crossed my mind that the problem may have arisen because new
> and delete in C++ have two distinct meanings. We have them as operators
> where they are user replaceable and overloadable. We also have them as
> non-operators where they are neither replaceable nor overloadable.
All uses of new or delete are as operators. What you're
referring to is the fact that user overloads of them work in a
decidedly different fashion than any other user overloads.
> int main(){
> void * memory = operator new(1000);
> mytype* = new mytype;
> }
> It is worth noting that many of the suggested preprocessor
> substitutions seem to assume that the programmer only uses the
> second case.
And also that he doesn't use any placement new.
--
James Kanze (GABI Software) email:james.kanze:gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]