From 5646193460372054081
X-Google-Thread: f78e5,60dc9044ee8e77d3
X-Google-Attributes: gidf78e5,public
X-Google-Language: ENGLISH,ASCII
Path: g2news1.google.com!news1.google.com!proxad.net!proxad.net!62.253.162.218.MISMATCH!news-in.ntli.net!newsrout1-win.ntli.net!ntli.net!peer-uk.news.demon.net!kibo.news.demon.net!news.demon.co.uk!demon!stump.algebra.com!devnull
From: AlbertoBarbati@libero.it (Alberto Barbati)
Newsgroups: comp.std.c++
Subject: Re: Strange new/new() problem
Date: Fri, 21 Jan 2005 04:31:11 GMT
Organization: [Infostrada]
Lines: 96
Sender: mail2news@demon.net
Approved: fjh@cs.mu.oz.au (Fergus Henderson , moderator of comp.std.c++)
Message-ID: <3a5Hd.9507$fs6.228289@twister2.libero.it>
References: <41ec486b$1@solnews.wv.mentorg.com>
NNTP-Posting-Host: news.news.demon.net
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
X-Trace: news.demon.co.uk 1106281881 25348 158.152.254.254 (21 Jan 2005 04:31:21 GMT)
X-Complaints-To: abuse@demon.net
NNTP-Posting-Date: Fri, 21 Jan 2005 04:31:21 +0000 (UTC)
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206)
X-MIME-Autoconverted: from 8bit to quoted-printable by mulga.cs.mu.OZ.AU id j0L4VEOK020913
X-Accept-Language: en, it
X-Virus-Scanned: by amavisd-new at cs.mu.OZ.AU
X-Path: comp-std-cpp-robomod!not-for-mail
X-Received: (from fjh@localhost)
	by mulga.cs.mu.OZ.AU (8.12.10+Sun/8.12.9/Submit) id j0L4VBbf020869;
	Fri, 21 Jan 2005 15:31:11 +1100 (EST)
X-NNTP-Posting-Date: Tue, 18 Jan 2005 11:03:43 MET
X-Enigmail-Supports: pgp-inline, pgp-mime
X-Enigmail-Version: 0.89.6.0
X-Delivered-To: std-c++@ucar.edu
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Newsgroups: comp.std.c++
Xref: g2news1.google.com comp.std.c++:3907

Fedor G. Pikus wrote:
> I've run into a little problem with operator new.
> Consider this example:
> struct data
> {
>     int i;
>     int j;
> };
> int main()
> {
>     data** p =3D new (data*)[5];
> }
>=20
> What the programmer wanted is to allocate an array of pointers, of=20
> course, and the parenthesis are unnecessary but arguably make reading=20
> the code easier.
>=20
> GCC compiled the code just fine, and did what the programmer wanted, bu=
t=20
> several other compilers refused. Error messages are of two types: eithe=
r=20
> it's "cannot assign data* to data**" or "[5] is unexpected". Comeau=20
> falls into the first cathegory, and I usually trust Comeau to get it=20
> right. Both messages suggest that these compilers interpret this code a=
s=20
> the placement new with "data *" being the location, even though it's a=20
> type, not a variable.

If I interpret the standard (=A75.3.4/1-3) correctly, the expression is=20
ill-formed. The new-expression is defined like this:

new-expression:
   ::opt new new-placementopt new-type-id new-initializeropt
   ::opt new new-placementopt ( type-id ) new-initializeropt

Because of the parantheses, the compiler should select the second form,=20
and that form does not allow the presence of a direct-new-declarator=20
(i.e.: the "[5]"). The "[5]" is thus not part of the new-expression and=20
cannot be intepreted as a subscripting operation because "new (data*)"=20
is not a postfix-expression. Syntax error.

That is:

1) in *no way* the expression is considered to be a placement syntax
2) gcc is wrong (it is probably using the first form of new-expression)
3) Comeau is also wrong (the error message suggests that it is=20
interpreting the "[5]" as a subscripting operation)
4) the compiler that reports "[5] is unexpected" is right

>=20
> Just for kicks, I tried this modification:
> data* p1 =3D new (data*)[5];
> on some of the compilers which complained about pointer conversion, and=
=20
> now the compilers are happy, program runs, and p is NULL.

Even if the code were legal (it's not), it would be undefined behaviour,=20
because you would be reading the 6th element of an array but passing in=20
a pointer to a single element. That would be equivalent to:

   data** temp =3D new (data*);
   data* p1 =3D temp[5]; // oops!!! temp does not point to
                       // an array of 6 elements

It's merely an accident that you got NULL. You could have got rubbish or
made the program crash.

>=20
> So, is the above (topmost) example legal in C++ or parenthesis are=20
> actually wrong, not just unnecessary?

If you put the parentheses you can no longer put a direct-new-declarator=20
  so their use in that context is wrong. If you wanted to improve=20
readability you might have used:

   typedef data* data_ptr;
   data_ptr* p =3D new data_ptr[5];

>=20
> Is the modification legal in C++ (Comeau says yes)? If the p1 line is=20
> legal, what is it doing, how is it parsed? "data*" is a location=20
> argument to placement new? What't the type then?

With or without the modification, the code is ill-formed, but with the=20
modification it is even worse.

HTH,

Alberto

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



