 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
mzdude Guest
|
Posted: Wed Aug 24, 2005 10:19 pm Post subject: Trying to understand the C++ Standard |
|
|
I am trying to synchronize my understanding of C++ with the standard.
When encountering the following code fragment, how does one go about
looking for the appropriate/relevant passages?
struct X
{
int a;
int b;
int c;
};
X MyFunc()
{
X x;
x.a = 1;
x.b = 2;
x.c = 3;
return x;
}
int main(int argc, char *argv[])
{
X x1 = MyFunc(); // Ok
X *pX = new X; // Ok
X *pBad = new MyFunc(); // Compiler error
X *pOk = new X( MyFunc() ); // Ok
size_t s = sizeof MyFunc(); // s is 12
size_t s2 = sizeof X; // s2 is 12
delete pX;
delete pBad;
delete pOk;
return 0;
}
MyFunc() returns a structure. When trying to "new" the results into
pBad I get a compiler error
"test.cpp(2 : error C2061: syntax error : identifier 'MyFunc'"
When I comment out the offending line and compile, the sizeof seems to
understand. But maybe that's an error. It seems to me the two should be
consistent.
I have rationalized that "new" is looking for a type. But doesn't that
apply for sizeof also. Why does it seem to behave differently. Can
anyone point me to the appropriate sections of the standard that might
explain this?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Thu Aug 25, 2005 12:18 pm Post subject: Re: Trying to understand the C++ Standard |
|
|
mzdude wrote:
| Quote: | struct X{...};
X MyFunc();
size_t s = sizeof MyFunc(); // s is 12
size_t s2 = sizeof X; // s2 is 12
I have rationalized that "new" is looking for a type. But doesn't that
apply for sizeof also. Why does it seem to behave differently. Can
anyone point me to the appropriate sections of the standard that might
explain this?
|
'sizeof' comes in two varieties, one takes a reference (or an expression
that evaluates to a reference) and that is what is invoked in the first
sizeof above. The other form takes a type, and that is what is invoked in
the second sizeof above - however, I was under the impression that it needs
to be 'sizeof (X)' and that the brackets are necessary.
With your use of new on an expression, there is no form equivalent to the
first sizeof above. There is however the idea to create a typeof operator;
with that, you could write 'new typeof MyFunc()'. Alternatively, you could
use template voodoo like the typeof lib in Boost.
Uli
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Thu Aug 25, 2005 12:21 pm Post subject: Re: Trying to understand the C++ Standard |
|
|
mzdude wrote:
| Quote: | I am trying to synchronize my understanding of C++ with the
standard. When encountering the following code fragment, how
does one go about looking for the appropriate/relevant
passages?
|
In the following code fragment, it's pretty straightforward.
Your questions concern the validity of different operands for
specific operators in an expression. Looking up the
corresponding operator in section 5 is sufficient.
(Regretfully, it isn't always that simple:-).)
| Quote: | struct X
{
int a;
int b;
int c;
};
X MyFunc()
{
X x;
x.a = 1;
x.b = 2;
x.c = 3;
return x;
}
int main(int argc, char *argv[])
{
X x1 = MyFunc(); // Ok
X *pX = new X; // Ok
X *pBad = new MyFunc(); // Compiler error
X *pOk = new X( MyFunc() ); // Ok
size_t s = sizeof MyFunc(); // s is 12
size_t s2 = sizeof X; // s2 is 12
|
According to the grammar, this line is also an error. Sizeof of
a type requires parentheses, e.g. "sizeof( X )". (Personally, I
find it clearer to always use parentheses with sizeof.)
None of the compilers I have access to accept it.
| Quote: | delete pX;
delete pBad;
delete pOk;
return 0;
}
MyFunc() returns a structure. When trying to "new" the results
into pBad I get a compiler error
"test.cpp(2 : error C2061: syntax error : identifier 'MyFunc'"
When I comment out the offending line and compile, the sizeof
seems to understand. But maybe that's an error. It seems to
me the two should be consistent.
|
Why? They do different things. As you say, new needs a type;
it needs to know what to allocate, and which constructor to
call. Sizeof can be used with either a type or an object --
both types and objects have a size.
| Quote: | I have rationalized that "new" is looking for a type. But
doesn't that apply for sizeof also. Why does it seem to
behave differently. Can anyone point me to the appropriate
sections of the standard that might explain this?
|
§5.3.3 describes sizeof, §5.3.4 new. The grammar at the
beginning of §5.3 gives the two variants of sizeof. (The
grammar for new is more complex, and is specified in §5.3.4.)
Note that an expression has a value, a type, an "lvalue-ness"
and possibly side effects. A type is just a type, and is never
an expression.
In the end, the difference comes down to the fact that asking
the size of an existing object (or value) makes sense, where as
new'ing an existing object is an oxymoron.
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ismail Pazarbasi Guest
|
Posted: Thu Aug 25, 2005 12:22 pm Post subject: Re: Trying to understand the C++ Standard |
|
|
You need to provide a "type" to new oprerator. MyFunc's type is
"function". You can't "new" a function.
Ismail
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Martin Bonner Guest
|
Posted: Thu Aug 25, 2005 11:14 pm Post subject: Re: Trying to understand the C++ Standard |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | In the end, the difference comes down to the fact that asking
the size of an existing object (or value) makes sense, where as
new'ing an existing object is an oxymoron.
|
I think that's a bit strong. It /could/ be used to mean what (I think)
the OP expected it to mean: that a new object is created which is copy
constructed from the existing object.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Meador Inge Guest
|
Posted: Thu Aug 25, 2005 11:43 pm Post subject: Re: Trying to understand the C++ Standard |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | Sizeof can be used with either a type or an object --
both types and objects have a size.
From my reading of the standard sizeof can only be applied to a type-id
or an expression. An object is a runtime construct where as sizeof is a |
compile-time construct. So how can sizeof truely be applied to an
object? An expression may mention the name of an object, but at that
point it is only a potential object and not an actual object.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
mzdude Guest
|
Posted: Fri Aug 26, 2005 9:38 am Post subject: Re: Trying to understand the C++ Standard |
|
|
James Kanze said
| Quote: | X *pBad = new MyFunc(); // Compiler error
X *pOk = new X( MyFunc() ); // Ok
size_t s = sizeof MyFunc(); // s is 12
size_t s2 = sizeof X; // s2 is 12
According to the grammar, this line is also an error. Sizeof of
a type requires parentheses, e.g. "sizeof( X )". (Personally, I
find it clearer to always use parentheses with sizeof.)
None of the compilers I have access to accept it.
|
I'm stuck in the Microsoft world. Both VC 6 and VC 7 accept sizeof
without parentheses.
Back to the original question about the standard. I have read 5.3.3
[expr.sizeof] and 5.3.4 [expr.new] many ... many times and I still
can't determine why
*p = new MyFuct();
is illegal.
§5.3.3/3 seems to indicate that sizeof MyFunc() is illegal. It says
"The sizeof operator can be applied to a pointer to function, but shall
not be applied directly to a function."
I guess the language lawyers would say that sizeof wasn't applied to
the function but to the return type of the function.
Just for the record, I don't code like the above example. I would
define
std::auto_ptr< X > MyFunc()
{
}
removing the need for *p = new MyFunc();
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
mzdude Guest
|
Posted: Fri Aug 26, 2005 9:39 am Post subject: Re: Trying to understand the C++ Standard |
|
|
Ismail said
| Quote: | You need to provide a "type" to new oprerator. MyFunc's type is
"function". You can't "new" a function.
|
I disagree that MyFunc's type is "function".
The statement return MyFunc(); doesn't return type "function" it
returns type X in this case.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Fri Aug 26, 2005 9:53 am Post subject: Re: Trying to understand the C++ Standard |
|
|
Meador Inge wrote:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
Sizeof can be used with either a type or an object --
both types and objects have a size.
From my reading of the standard sizeof can only be applied to a type-id
or an expression. An object is a runtime construct where as sizeof is a
compile-time construct. So how can sizeof truely be applied to an
object? An expression may mention the name of an object, but at that
point it is only a potential object and not an actual object.
|
The expression given to sizeof is implicitly converted to the resulting type
(Note: it is not evaluated at runtime!) and that type's size is 'returned'.
Now, since a simple variable 'x' is also an expression, 'sizeof x' works
with it.
Uli
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Sat Aug 27, 2005 10:04 am Post subject: Re: Trying to understand the C++ Standard |
|
|
Meador Inge wrote:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
Sizeof can be used with either a type or an object --
both types and objects have a size.
From my reading of the standard sizeof can only be applied to
a type-id or an expression. An object is a runtime construct
where as sizeof is a compile-time construct. So how can
sizeof truely be applied to an object? An expression may
mention the name of an object, but at that point it is only a
potential object and not an actual object.
|
I was using the term (very) loosely. Strictly speaking, as you
say, sizeof applies to an expression -- an expression has a
type, and sizeof returns the size of that type. Generally
speaking, of course, and expression has a value as well, and
informally, that value can be considered an "object".
(Formally, using the definitions in the C++ standard, that value
is an object if and only if it is either an lvalue or has a
class type. But informally...)
Note that there is an additional requirement: the type of the
expression must be complete. In particular, sizeof( f() ),
where f returns a void, or sizeof( *p ), where p is a void*, is
not legal.
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Sat Aug 27, 2005 10:05 am Post subject: Re: Trying to understand the C++ Standard |
|
|
mzdude wrote:
| Quote: | James Kanze said
X *pBad = new MyFunc(); // Compiler error
X *pOk = new X( MyFunc() ); // Ok
size_t s = sizeof MyFunc(); // s is 12
size_t s2 = sizeof X; // s2 is 12
According to the grammar, this line is also an error. Sizeof
of a type requires parentheses, e.g. "sizeof( X
)". (Personally, I find it clearer to always use parentheses
with sizeof.) None of the compilers I have access to accept
it.
I'm stuck in the Microsoft world. Both VC 6 and VC 7 accept
sizeof without parentheses.
|
Send in a bug report:-). The standard requires a diagnostic.
| Quote: | Back to the original question about the standard. I have read
5.3.3 [expr.sizeof] and 5.3.4 [expr.new] many ... many times
and I still can't determine why
*p = new MyFuct();
is illegal.
|
My question would be more: what makes you think it is legal?
The grammar in §5.3.4 says that a new expression can be either:
::[opt] new new-placement[opt] new-type-id new-initializer[opt]
or
::[opt] new new-placement[opt] ( type-id ) new-initializer[opt]
There are no other forms. Thus, the new keyword must be
followed by a new-placement, a new-type-id or "( type-id )".
Of these, both new-placement and "( type-id )" must begin with a
'(', so the only case to consider here is new-type-id. And if
we look immediately below, we see that a new-type-id must begin
with a type-specifier-seq, which is defined in §8.1. But even
without looking that far, I would assume that a
type-specifier-seq is a sequence of one or more type-specifiers,
and type-specifiers are defined, not surprisingly, in §7.1.5
Type specifiers. Without going into details, basically, a
type-specifier can only be a keyword or a user defined type
name. Since MyFunc is neither, "new MyFunc" cannot parse,
regardless of what follows or precedes.
| Quote: | §5.3.3/3 seems to indicate that sizeof MyFunc() is illegal. It
says "The sizeof operator can be applied to a pointer to
function, but shall not be applied directly to a function."
I guess the language lawyers would say that sizeof wasn't
applied to the function but to the return type of the
function.
|
No. sizeof is applied to an expression. The expression you
gave it was not a function, but the invocation of a function.
What the sentence you quote forbids is something like:
size_t s = sizeof MyFunc ;
Since the type of a function invocation expression (operator
()) is the return type of the function, this is effectively what
sizeof is being applied to in your example.
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Sat Aug 27, 2005 10:08 am Post subject: Re: Trying to understand the C++ Standard |
|
|
Ismail Pazarbasi wrote:
| Quote: | You need to provide a "type" to new oprerator. MyFunc's type
is "function". You can't "new" a function.
|
You need to provide a type to the new operator. MyFunc() is an
expression, not a type. It's a syntax error, not a violation of
a semantic constraint.
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Sat Aug 27, 2005 10:12 am Post subject: Re: Trying to understand the C++ Standard |
|
|
Ismail Pazarbasi wrote:
| Quote: | You need to provide a "type" to new oprerator. MyFunc's type
is "function". You can't "new" a function.
|
You need to provide a type to the new operator. MyFunc() is an
expression, not a type. It's a syntax error, not a violation of
a semantic constraint.
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Sat Aug 27, 2005 10:13 am Post subject: Re: Trying to understand the C++ Standard |
|
|
mzdude wrote:
| Quote: | James Kanze said
X *pBad = new MyFunc(); // Compiler error
X *pOk = new X( MyFunc() ); // Ok
size_t s = sizeof MyFunc(); // s is 12
size_t s2 = sizeof X; // s2 is 12
According to the grammar, this line is also an error. Sizeof
of a type requires parentheses, e.g. "sizeof( X
)". (Personally, I find it clearer to always use parentheses
with sizeof.) None of the compilers I have access to accept
it.
I'm stuck in the Microsoft world. Both VC 6 and VC 7 accept
sizeof without parentheses.
|
Send in a bug report:-). The standard requires a diagnostic.
| Quote: | Back to the original question about the standard. I have read
5.3.3 [expr.sizeof] and 5.3.4 [expr.new] many ... many times
and I still can't determine why
*p = new MyFuct();
is illegal.
|
My question would be more: what makes you think it is legal?
The grammar in §5.3.4 says that a new expression can be either:
::[opt] new new-placement[opt] new-type-id new-initializer[opt]
or
::[opt] new new-placement[opt] ( type-id ) new-initializer[opt]
There are no other forms. Thus, the new keyword must be
followed by a new-placement, a new-type-id or "( type-id )".
Of these, both new-placement and "( type-id )" must begin with a
'(', so the only case to consider here is new-type-id. And if
we look immediately below, we see that a new-type-id must begin
with a type-specifier-seq, which is defined in §8.1. But even
without looking that far, I would assume that a
type-specifier-seq is a sequence of one or more type-specifiers,
and type-specifiers are defined, not surprisingly, in §7.1.5
Type specifiers. Without going into details, basically, a
type-specifier can only be a keyword or a user defined type
name. Since MyFunc is neither, "new MyFunc" cannot parse,
regardless of what follows or precedes.
| Quote: | §5.3.3/3 seems to indicate that sizeof MyFunc() is illegal. It
says "The sizeof operator can be applied to a pointer to
function, but shall not be applied directly to a function."
I guess the language lawyers would say that sizeof wasn't
applied to the function but to the return type of the
function.
|
No. sizeof is applied to an expression. The expression you
gave it was not a function, but the invocation of a function.
What the sentence you quote forbids is something like:
size_t s = sizeof MyFunc ;
Since the type of a function invocation expression (operator
()) is the return type of the function, this is effectively what
sizeof is being applied to in your example.
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Meador Inge Guest
|
Posted: Sat Aug 27, 2005 10:17 am Post subject: Re: Trying to understand the C++ Standard |
|
|
Ulrich Eckhardt wrote:
| Quote: | Meador Inge wrote:
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Sizeof can be used with either a type or an object --
both types and objects have a size.
From my reading of the standard sizeof can only be applied to a type-id
or an expression. An object is a runtime construct where as sizeof is a
compile-time construct. So how can sizeof truely be applied to an
object? An expression may mention the name of an object, but at that
point it is only a potential object and not an actual object.
The expression given to sizeof is implicitly converted to the resulting type
(Note: it is not evaluated at runtime!) and that type's size is 'returned'.
Now, since a simple variable 'x' is also an expression, 'sizeof x' works
with it.
Uli
|
I understand the mechanism for how an objects name can be mentioned in
an expression that sizeof is applied to. The "So how can sizeof truely
be applied to an object?" was meant to be rhetorical. My whole point
was (and is) that sizeof is never really applied directly to an object
since objects are runtime entities.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|