T
thomas
Hi,
int **p = new (int) *[30]; //ERROR
int **p = new (int*)[30]; //ERROR
----------
Any difference between them?
Evaluates as:
int** p = new (int (*([30]));
An array of 30 int*.
int **p = new (int) *[30]; //ERROR
int** p = (new (int)) * [30];
Don't know what the compiler is supposed to make of the [30],
given that there's no address expression to the left of it.
(And the '*' is multiplication.)
int **p = new (int*)[30]; //ERROR
int** p = (new (int*))[30];
Here, the initialization expression is a syntactically legal
expression (but would have undefined behavior at runtime),
but
it doesn't have the type int**: the new expression returns an
int** (pointing to a single uninitialized int*), but
dereferencing it (remember, a is the same as *(a+b)) results
in an int*.
* James Kanze:Evaluates as:
int** p = new (int (*([30]));
An array of 30 int*.int** p = (new (int)) * [30];int **p = new (int) *[30]; //ERROR
Don't know what the compiler is supposed to make of the [30],
given that there's no address expression to the left of it.
(And the '*' is multiplication.)int** p = (new (int*))[30];int **p = new (int*)[30]; //ERROR
Here, the initialization expression is a syntactically legal
expression (but would have undefined behavior at runtime),
new expressions are a wilderness of special case rules.
On reading your statement I thought huh, that must a placement
form syntactically.
But as it turned out[1] I was wrong[2] about why you're wrong
here,
<example>
"ComeauTest.c", line 3: error: this operator is not allowed at this point; use
parentheses
int **p = new (int*)[30];
^
"ComeauTest.c", line 3: error: a value of type "int *" cannot be used to initialize
an entity of type "int **"
int **p = new (int*)[30];
</example>but
it doesn't have the type int**: the new expression returns an
int** (pointing to a single uninitialized int*), but
dereferencing it (remember, a is the same as *(a+b)) results
in an int*.
Right, but first it must pass muster syntactically.
I ask this question because I thought "int *" is just like a type like
"int" and
just like
I thought it is obvious and natural until problem occurs.
I tried the expression
-----
int main(){
int **p = new (int (*([30])));}
-----
and got error message again in VC2005
----
1>------ Build started: Project: test, Configuration: Debug Win32
------
1>Compiling...
1>test.cpp
1>e:\lab\test\test\test.cpp(3) : error C3409: empty attribute block is
not allowed
1>e:\lab\test\test\test.cpp(3) : error C2143: syntax error : missing
']' before 'constant'
1>e:\lab\test\test\test.cpp(3) : error C2059: syntax error :
'constant'
1>e:\lab\test\test\test.cpp(3) : error C2059: syntax error : ')'
1>Build log was saved at "file://e:\Lab\test\test\Debug\BuildLog.htm"
1>test - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped
==========
----
So I think more clarification may be required.
James said:But as it turned out[1] I was wrong[2] about why you're wrong
here,<example>
"ComeauTest.c", line 3: error: this operator is not allowed at this
point; use
parentheses
int **p = new (int*)[30];
^"ComeauTest.c", line 3: error: a value of type "int *" cannot be used to
initialize
an entity of type "int **"
int **p = new (int*)[30];
</example>but
it doesn't have the type int**: the new expression returns an
int** (pointing to a single uninitialized int*), but
dereferencing it (remember, a is the same as *(a+b)) results
in an int*.
Right, but first it must pass muster syntactically.
It does. At least according to my copy of the epxression. The
new expression is "new (int*)". And that gets used as the left
operand of the [] expression. I don't know what Comeau is
complaining about with "this operator is not allowed at this
point---the grammar clearly allows it. (The new expression, in
this case, matches "::[opt] new new-placement[opt] ( type-id )
new-initializer[opt]", with none of the optional parts present.
James said:"ComeauTest.c", line 3: error: a value of type "int *" cannot be used to
initialize
an entity of type "int **"
int **p = new (int*)[30];
</example>
but it doesn't have the type int**: the new expression
returns an int** (pointing to a single uninitialized
int*), but dereferencing it (remember, a is the same
as *(a+b)) results in an int*.
Right, but first it must pass muster syntactically.
It does. At least according to my copy of the epxression.
The new expression is "new (int*)". And that gets used as
the left operand of the [] expression. I don't know what
Comeau is complaining about with "this operator is not
allowed at this point---the grammar clearly allows it. (The
new expression, in this case, matches "::[opt] new
new-placement[opt] ( type-id ) new-initializer[opt]", with
none of the optional parts present.
First, i want to agree that new expressions are a wilderness
of special rules xD
I think the problem with "new (int*)[30]" is that "new (int*)"
is not a postfix-expression. new-expression is branching off
unary-expression, so if you want a new-expression on the left
of op[], you need parens.
However, think that comeau is wrong at another place on
parsing new- expressions, when it accepts "new (int[n]);" and
"new (int[0, 1]);" when n is a runtime value. "type-id" won't
accept any of these. I'm interested to see what they do in
C++0x when they need to check this in SFINAE contexts.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.