From 7325670559087290541
X-Google-Thread: f78e5,60dc9044ee8e77d3
X-Google-Attributes: gidf78e5,public
X-Google-Language: ENGLISH,ASCII
Return-Path: <devnull@stump.algebra.com>
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
Path: g2news1.google.com!news4.google.com!newsfeed.stanford.edu!comp-std-cpp-robomod!not-for-mail
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
Delivered-To: std-c++@ucar.edu
From: kanze@gabi-soft.fr
Newsgroups: comp.std.c++
Subject: Re: Strange new/new() problem
Organization: http://groups.google.com
Message-ID: <1106665383.068956.20250@z14g2000cwz.googlegroups.com>
References: <41ec486b$1@solnews.wv.mentorg.com>
   <1106038227.037429.135930@c13g2000cwb.googlegroups.com>
   <41ed4a9e$1@solnews.wv.mentorg.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
X-Trace: posting.google.com 1106665386 13905 127.0.0.1 (25 Jan 2005 15:03:06 GMT)
X-Complaints-To: groups-abuse@google.com
NNTP-Posting-Date: Tue, 25 Jan 2005 15:03:06 +0000 (UTC)
User-Agent: G2/0.2
Complaints-To: groups-abuse@google.com
Injection-Info: z14g2000cwz.googlegroups.com; posting-host=62.160.54.162;
   posting-account=qsfl8gwAAABZGaLp2a7FeTfDkJamzWYW
X-Virus-Scanned: by amavisd-new at cs.mu.OZ.AU
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from quoted-printable to 8bit by mulga.cs.mu.OZ.AU id j0PF3SxM014351
Approved: Fergus Henderson <fjh@cs.mu.oz.au>, moderator of comp.std.c++
X-Virus-Scanned: by amavisd-new at cs.mu.OZ.AU
Date: Tue, 25 Jan 2005 09:25:36 CST
Xref: g2news1.google.com comp.std.c++:3956

"Fedor G. Pikus" wrote:
> msalters wrote:
> > "Fedor G. Pikus" wrote:

> >>Consider this example:
> >>struct data { /****/ };
> >>int main() {
> >>     data** p = new (data*)[5];
> >>}

> >>What the programmer wanted is to allocate an array of
> >>pointers, of course, and the parenthesis are unnecessary but
> >>arguably make reading the code easier.

> > In this case, yes. 5.3.4/3 shows precisely why parenthesis
> > are sometimes needed.

Actually, adding incorrect parentheses can never make the code
easier to read.

> >>GCC compiled the code just fine, and did what the programmer
> >>wanted, but several other compilers refused. Error messages
> >>are of two types: either it's "cannot assign data* to
> >>data**" or "[5] is unexpected". Comeau falls into the first
> >>cathegory, and I usually trust Comeau to get it right. Both
> >>messages suggest that these compilers interpret this code as
> >>the placement new with "data *" being the location, even
> >>though it's a type, not a variable.

> > There are two possible forms of a new-expression:
> > new new-placement_opt new-type-id new-initializer_opt
> > new new-placement_opt( typeid ) new-initializer_opt

> > Your form is /not/ the latter.

It sure looks like the latter to me.  It certainly can't be the
former, since a new-type-id cannot begin with a parentheses.

> > [5] cannot be parsed as a new-initializer.

It's not a new-initializer.  It's a [] operator.  Applied to the
pointer returned by new.  Perfectly legal syntactically.

> > The next step is to look at the new-type-id which has the
> > form type-specifier_seq new-declarator_opt

> > type-specifier_seq is just a sequence of
> > type-specifier's. There are quite a number of possible
> > type-specifier's, but none start with a (. The optional
> > new-placement part /does/ start with an (, so the confusion
> > of the compiler is fully understandable.

What confusion?  The symbol data is a type name.  A
new-placement cannot begin with a type name, so that must be
excluded. A typeid can begin with a type name; in fact, it must
begin with a type name.  So we are manifestedly in the case two
above, where the typeid is in parentheses.

> It's understandable, but what's the correct syntax?
> Specifically, is the following line legal C++:

> p = new (data*)[5];

It depends on the type of p, and what you mean by legal.  If p
is a data**, no, it's a type error, which must be diagnosed by
the compiler.  If p is a data*, the expression is syntactically
legal, but has undefined behavior at run-time.

> If it is, what is the type of the result, data** or data*?
> Both Comeau and GCC say that this line is legal, Comeau says
> that result is data* and always NULL,

I very much doubt that Comeau says that the result is always
NULL.  It's undefined behavior, and the result could be just
about anything.  Try something like the following before the
expression:

unsigned* q = new unsigned[ 100 ] ;
std::uninitialized_fill_n( q, q + 100, 0xDEADBEEF ) ;
delete [] q ;
data* p = new (data*)[ 5 ] ;

With at least one of the implementations I've used, this will
result in p == 0xDEADBEEF.  (But of course, this isn't
guaranteed either.)

> GCC says that result is data** and points to allocated
> memory. Who is right?

Comeau, obviously:-).  In this case, I think that g++ is wrong
intentionally; that they feel that their interpretation is more
useful.  It probably is more useful, given that I can't think of
any way to use the correct interpretation without getting
undefined behavior, but there should at least be a means of
turning the extension off -- personnally, I would simply follow
the standard, but give a warning.

--
James Kanze           GABI Software         http://www.gabi-soft.fr
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.jamesd.demon.co.uk/csc/faq.html                       ]



