Topic: Strange new/new() problem


Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sat, 22 Jan 2005 03:47:48 GMT
Raw View
kanze@gabi-soft.fr wrote:
> "Fedor G. Pikus" wrote:
>
>
>>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".
>
> The latter is only a warning, I hope.
>
> <snip>
>
> One could argue for a special rule barring the immediate
> application of [] to the results of a new expression -- I can't
> think of a case off hand where it is useful.  Orthogonality
> would argue against such a hack, of course, but that shouldn't
> be the only consideration.
>

According to the interpretation I gave in my other post, the compiler
should indeed give an error, not a warning. There's no need for a
special rule to bar the application of [] to the result of new, because
it seems to me that the current rules already make such application
ill-formed. That's because [] operates on a postfix-expression and "new
(data*)" is not a postfix-expression.

Is there's something I'm missing?

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                       ]





Author: comeau@panix.com (Greg Comeau)
Date: Sat, 22 Jan 2005 03:47:55 GMT
Raw View
In article <41ec486b$1@solnews.wv.mentorg.com>,
Fedor G. Pikus <fedor_pikus@mentorg.com> wrote:
>I've run into a little problem with operator new.
>Consider this example:
>struct data
>{
>     int i;
>     int j;
>};
>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.

That does not request an array of pointers.  These don't work as decls:

(data *)p[5];
(data *p2)[5];

An array of pointers to data is 'data *[5]'

>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.

It's not being interpreted as a placement new, but as a 'new data *'

>Just for kicks, I tried this modification:
>data* p1 = new (data*)[5];
>on some of the compilers which complained about pointer conversion, and
>now the compilers are happy,

But the program is still wrong.

>program runs,

Well, at least does not fail.

>and p is NULL.

Appears to be thus far in your tests.

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

Wrong IMO.

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

You've sub-expressions, starting with 'new data *'.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

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





Author: kanze@gabi-soft.fr
Date: Tue, 25 Jan 2005 09:25:36 CST
Raw View
"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                       ]





Author: kanze@gabi-soft.fr
Date: Tue, 25 Jan 2005 12:00:43 CST
Raw View
Alberto Barbati wrote:
> kanze@gabi-soft.fr wrote:
> > "Fedor G. Pikus" wrote:

> >>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".

> > The latter is only a warning, I hope.

> > <snip>

> > One could argue for a special rule barring the immediate
> > application of [] to the results of a new expression -- I
> > can't think of a case off hand where it is useful.
> > Orthogonality would argue against such a hack, of course,
> > but that shouldn't be the only consideration.

> According to the interpretation I gave in my other post, the
> compiler should indeed give an error, not a warning.  There's
> no need for a special rule to bar the application of [] to the
> result of new, because it seems to me that the current rules
> already make such application ill-formed. That's because []
> operates on a postfix-expression and "new (data*)" is not a
> postfix-expression.

That's a good point.  I simply applied the maximum munch rule to
the new expression, to determine its end, and then looked at
what was left.  Since the new expression can't be broken up, the
only issue of precedence is with the = operator, and obviously,
[] has precedence.  But as you point out, the standard doesn't
define expressions in terms of precedence, but by means of
productions.  You're right, and there is no production which can
produce the expression new (data*)[5].

Which means that the expression is illegal, and a compiler is
required to emit a diagnostic.

And that Comeau is wrong if it allows assigning the results to a
data*:-).

(Something like (new (data*))[5] is obviously legal, but IMHO,
that's really a case of "you asked for it, you got it".  I can't
quite see it occuring because of an incorrect understanding on
the part of the programmer.)

> Is there's something I'm missing?

I don't think so.  I think I was missing something.

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





Author: fedor_pikus@mentorg.com ("Fedor G. Pikus")
Date: Mon, 17 Jan 2005 23:31:42 GMT
Raw View
I've run into a little problem with operator new.
Consider this example:
struct data
{
     int i;
     int j;
};
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.

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.

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

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

Is the modification legal in C++ (Comeau says yes)? If the p1 line is
legal, what is it doing, how is it parsed? "data*" is a location
argument to placement new? What't the type then?
--
                                   Fedor G. Pikus
http://www.pikus.net/~pikus/

Mentor Graphics Corporation         | Phone: (503) 685-4857
8405 SW Boeckman Road               | FAX:   (503) 685-1239
Wilsonville, Oregon 97070           |

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





Author: "msalters" <Michiel.Salters@logicacmg.com>
Date: Tue, 18 Jan 2005 10:34:35 CST
Raw View
"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.

> 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. [5] cannot be parsed as a
new-initializer. 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.
HTH,
Michiel Salters

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





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Fri, 21 Jan 2005 04:31:11 GMT
Raw View
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                       ]





Author: fedor_pikus@mentorg.com ("Fedor G. Pikus")
Date: Fri, 21 Jan 2005 04:31:28 GMT
Raw View
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.
>
>
>>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. [5] cannot be parsed as a
> new-initializer. 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.

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

p = new (data*)[5];

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, GCC says that result is data** and points to allocated
memory. Who is right?

> HTH,
> Michiel Salters
>
> ---
> [ 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                       ]
>


--
                                   Fedor G. Pikus
http://www.pikus.net/~pikus/

Mentor Graphics Corporation         | Phone: (503) 685-4857
8405 SW Boeckman Road               | FAX:   (503) 685-1239
Wilsonville, Oregon 97070           |

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





Author: kanze@gabi-soft.fr
Date: Thu, 20 Jan 2005 22:31:31 CST
Raw View
"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 = 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.

Why didn't the programmer write what he wanted, then.  And if
the programmer wanted additional parentheses, he should at least
put them someplace they make sense, e.g.:

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

A pointer to an array[ 5 ] of data.  (I can't make any sense out
of something like (data*)[ 5 ].  Applying the parentheses, one
gets a pointer to a data of array[ 5 ].  But that doesn't make
any sense.)

> GCC compiled the code just fine,

Then GCC has a serious bug, because there is a type error in the
program.

> 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".

The latter is only a warning, I hope.

> 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.

I suspect rather that both compilers simply interpret this to
mean what is written.  The type expression for the new is
(data*), so the new operator allocates a single data* and
returns its address.  And then applies the [5] to the pointer
which is returned (which, of course, results in undefined
behavior, but [0] wouldn't).

One could argue for a special rule barring the immediate
application of [] to the results of a new expression -- I can't
think of a case off hand where it is useful.  Orthogonality
would argue against such a hack, of course, but that shouldn't
be the only consideration.

More generally, the whole business of array new versus scalar
new is broken.  But I can't think of any way of fixing it
without also fixing C style arrays (which is what is really
broken), and the amount of code that would break is
unthinkable.  So I guess we're just stuck with it.

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

On a compiler with bounds checking, you would get a runtime
error.  You've allocated a scalar, and returned a pointer to it;
then you add 6 to that pointer and dereference.

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

The parentheses are legal.  They delimit the type expression of
the new expression.  The total statement is illegal, because
dereferencing a data** results in a data*, not a data*.

> Is the modification legal in C++ (Comeau says yes)?

It's syntactically legal, but results in undefined behavior.

Remember how the [] operator is defined.  new (data*)[5] is the
equivalent of *(new (data*) + 5).

> If the p1 line is legal, what is it doing, how is it parsed?
> "data*" is a location argument to placement new?

No.  It's the type expression.

> What't the type then?

data*.

That is, after all, why you put it in parentheses, no?  So that
the [] wouldn't be part of the type expression.

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





Author: comeau@panix.com (Greg Comeau)
Date: Fri, 21 Jan 2005 19:12:04 GMT
Raw View
In article <1106064562.182462.247340@c13g2000cwb.googlegroups.com>,
 <kanze@gabi-soft.fr> wrote:
>"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 = 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.
>
>Why didn't the programmer write what he wanted, then.  And if
>the programmer wanted additional parentheses, he should at least
>put them someplace they make sense, e.g.:
>
>data** p = new data (*)[ 5 ] ;
>...


I think James has it right:


G:\tmp>type new5.cpp
struct data
{
  int i;
  int j;
};

int main()
{
  data** p = new (data*)[5]; // line 9
  data** p2 = (new (data*))[5]; // line 10
  data** p3 = *(new (data*) + 5); // line 11
}

The problem is you can't allocate one pointer and then expect
to [5] it, since that memory does not exist.   Anyway, upon [5]ing
it, the intialization expression goes from a data ** to a data *,
hence:


G:\tmp>g++ -Wall -ansi -pedantic new5.cpp
new5.cpp: In function `int main()':
new5.cpp:9: warning: ANSI C++ forbids array dimensions with parenthesized type in new
new5.cpp:10: initialization to `data **' from `data *'
new5.cpp:11: initialization to `data **' from `data *'
new5.cpp:11: warning: unused variable `struct data ** p3'
new5.cpp:10: warning: unused variable `struct data ** p2'
new5.cpp:9: warning: unused variable `struct data ** p'

G:\tmp>como --vc71 --A new5.cpp
Comeau C/C++ 4.3.4.1 (Sep 19 2004 11:33:48) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing.  All rights reserved.
MODE:strict errors C++

"new5.cpp", line 9: error: a value of type "data *" cannot be used to
          initialize an entity of type "data **"
    data** p = new (data*)[5]; // line 9
               ^

"new5.cpp", line 10: error: a value of type "data *" cannot be used to
          initialize an entity of type "data **"
    data** p2 = (new (data*))[5]; // line 10
                ^

"new5.cpp", line 11: error: a value of type "data *" cannot be used to
          initialize an entity of type "data **"
    data** p3 = *(new (data*) + 5); // line 11
                ^

3 errors detected in the compilation of "new5.cpp".

G:\tmp>cl /Za new5.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

new5.cpp
new5.cpp(9) : error C2143: syntax error : missing ';' before '['
new5.cpp(9) : error C3400: 'string': unexpected token/character encountered in attribute block
new5.cpp(10) : error C2440: 'initializing' : cannot convert from 'data *' to 'data ** '
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
new5.cpp(11) : error C2440: 'initializing' : cannot convert from 'data *' to 'data ** '
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

G:\tmp>bcc32 new5.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
new5.cpp:
Error E2034 new5.cpp 9: Cannot convert 'data *' to 'data * *' in function main()
Error E2034 new5.cpp 10: Cannot convert 'data *' to 'data * *' in function main()
Error E2034 new5.cpp 11: Cannot convert 'data *' to 'data * *' in function main()
Warning W8004 new5.cpp 12: 'p3' is assigned a value that is never used in function main()
Warning W8004 new5.cpp 12: 'p2' is assigned a value that is never used in function main()
Warning W8004 new5.cpp 12: 'p' is assigned a value that is never used in function main()
*** 3 errors in Compile ***

...



Since I recall it's ill-formed, I'll take any of the above, as it
just seems to come down to which angle you want to take on it.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

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