Topic: interpretation of the expression new (int*)[10]
Author: kanze@gabi-soft.de (James Kanze)
Date: Fri, 1 Mar 2002 18:31:33 GMT Raw View
Moritz Franosch <jfranosc@physik.tu-muenchen.de> wrote in message
news:<rxx1yf669tb.fsf@synapse.t30.physik.tu-muenchen.de>...
> Please consider the following C++ program
> int main() {
> int** p;
> p=new int*[10]; // 1
> p=new (int*)[10]; // 2
> p=(new (int*))[10]; // 3
> }
> According to the C++ standard, are 1 and 2 equivalent or 2 and 3?
2 and 3 are equivalent.
> In my interpretation of the standard, 1 means new returns a pointer
> to an array of 10 integers,
1 allocates 10 pointers to int, and returns a pointer to the first,
thus, an int**. Perfectly legal.
> 2 is equivalent to 3 and 3 means
> p=(new (int*))+10.
Not quite. The sequence "(int*)[10]", isn't a legal type name, so the
new expression in 2 is "new (int*)" -- which is the equivalent to the
new expression in 3. In both cases, a single int* is allocated, and
it's address is returned. In both cases, the [10] then adds 10 to the
returned pointer, and dereferences it -- undefined behavior, but since
the result of dereferencing an int** is an int*, the compiler should
complain about a type mismatch.
> GCC version 3.0.2 sees 1 and 2 as equivalent, which is wrong. Intel
> C++ version 5.0.1 is standard compliant.
[...]
> I can't see a way to get '(int*)' for a type-specifier-seq, so 'new
> (int*)[10]' is no new-expression, but 'new (int*)' is and therefore
> 'new (int*)[10]' (2) must be interpreted as '(new (int*))[10]' (3).
Exactly. You just got the types a bit mixed up.
> Is my interpretation of the standard right? If so, I'll send a bug
> report to the GCC team.
Do so.
--
James Kanze mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
-- Conseils en informatique orient e objet
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany, T l.: +49 (0)69 19 86 27
---
[ 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.research.att.com/~austern/csc/faq.html ]
Author: Moritz Franosch <jfranosc@physik.tu-muenchen.de>
Date: Wed, 27 Feb 2002 14:39:09 CST Raw View
Please consider the following C++ program
int main() {
int** p;
p=new int*[10]; // 1
p=new (int*)[10]; // 2
p=(new (int*))[10]; // 3
}
According to the C++ standard, are 1 and 2 equivalent or 2 and 3?
In my interpretation of the standard, 1 means new returns a pointer to
an array of 10 integers, 2 is equivalent to 3 and 3 means
p=(new (int*))+10.
GCC version 3.0.2 sees 1 and 2 as equivalent, which is wrong. Intel
C++ version 5.0.1 is standard compliant.
In the following, I try to proof that 2 is not equivalent to 1
according to my "November 1997 Draft C++ Standard".
A new-expression is
new-expression:
::opt new new-placementopt new-type-id new-initializeropt
::opt new new-placementopt ( type-id ) new-initializeropt
For the moment let's take the second rule, so we get
new ( type-id ) new-initializer
But a new-initializer
new-initializer:
( expression-listopt )
must start with '(', thus we cannot get 'new (int*)[10]' as a
new-expression in this way.
It remains to substitute new-expression by
new new-type-id
new-type-id:
type-specifier-seq new-declaratoropt
new-declarator:
ptr-operator new-declaratoropt
direct-new-declarator
direct-new-declarator:
[ expression ]
direct-new-declarator [ constant-expression ]
We continue with
new type-specifier-seq new-declarator
new type-specifier-seq ptr-operator direct-new-declarator
or
new type-specifier-seq direct-new-declarator
new type-specifier-seq *[10]
or
new type-specifier-seq [10]
type-specifier-seq:
type-specifier type-specifier-seqopt
type-specifier:
simple-type-specifier
class-specifier
enum-specifier
elaborated-type-specifier
cv-qualifier
simple-type-specifier:
::opt nested-name-specifieropt type-name
::opt nested-name-specifier template template-id
char
wchar_t
bool
short
int
long
signed
unsigned
float
double
void
elaborated-type-specifier:
class-key ::opt nested-name-specifieropt identifier
enum ::opt nested-name-specifieropt identifier
typename ::opt nested-name-specifier identifier
typename ::opt nested-name-specifier templateopt template-id
I can't see a way to get '(int*)' for a type-specifier-seq, so 'new
(int*)[10]' is no new-expression, but 'new (int*)' is and therefore
'new (int*)[10]' (2) must be interpreted as '(new (int*))[10]' (3).
Is my interpretation of the standard right? If so, I'll send a bug
report to the GCC team.
Thank you for your help,
Moritz
---
[ 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.research.att.com/~austern/csc/faq.html ]
Author: Michael Spencer <michael_spencer@btclick.com>
Date: Thu, 28 Feb 2002 02:21:46 GMT Raw View
Moritz Franosch wrote:
>
> Please consider the following C++ program
>
> int main() {
> int** p;
> p=new int*[10]; // 1
> p=new (int*)[10]; // 2
> p=(new (int*))[10]; // 3
> }
>
> According to the C++ standard, are 1 and 2 equivalent or 2 and 3?
>
> In my interpretation of the standard, 1 means new returns a pointer to
> an array of 10 integers, 2 is equivalent to 3 and 3 means
> p=(new (int*))+10.
>
In 1, new allocates an array of 10 pointer to ints, so the return type
is int **. 3 is equivalent to p=*(new (int*) + 10), so you're
assigning an int * to an int **.
Not sure how 2 compiles. I see it as a syntax error. If it's an
array access (like 3), then new (int*) must be a postfix expression:
postfix-expression -> postfix-expression [ expression ]
But I don't see how postfix-expression derives new-expression:
postfix-expression -> ... -> new-expression
Mike
> Thank you for your help,
>
> Moritz
>
> ---
> [ 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.research.att.com/~austern/csc/faq.html ]
---
[ 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.research.att.com/~austern/csc/faq.html ]
Author: Moritz Franosch <jfranosc@physik.tu-muenchen.de>
Date: Thu, 28 Feb 2002 16:11:39 GMT Raw View
Michael Spencer <michael_spencer@btclick.com> writes:
> Moritz Franosch wrote:
> >
> > Please consider the following C++ program
> >
> > int main() {
> > int** p;
> > p=new int*[10]; // 1
> > p=new (int*)[10]; // 2
> > p=(new (int*))[10]; // 3
> > }
> >
> > According to the C++ standard, are 1 and 2 equivalent or 2 and 3?
>
> In 1, new allocates an array of 10 pointer to ints, so the return type
> is int **. 3 is equivalent to p=*(new (int*) + 10), so you're
> assigning an int * to an int **.
Yes, your version is right of course. GCC 3.0.2 only warns in case 3
that an int * is assigned to an int **, Intel 5.0.1 gives the same
warning in cases 2 and 3.
> Not sure how 2 compiles. I see it as a syntax error.
Then both compilers would be wrong, could well be.
> If it's an array access (like 3), then new (int*) must be a postfix
> expression:
>
> postfix-expression -> postfix-expression [ expression ]
>
> But I don't see how postfix-expression derives new-expression:
>
> postfix-expression -> ... -> new-expression
Difficult to show that it is not possible. But I see your
point. Because of
postfix-expression:
primary-expression
postfix-expression [ expression ]
...
we probably need
primary-expression [10]
and have to get from primary-expression to a new-expression, but
primary-expression:
literal
this
( expression )
id-expression
and so we have to use the parentheses '( expression )'.
Thank you for your additional insight,
Moritz
---
[ 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.research.att.com/~austern/csc/faq.html ]