Archives
D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
|
c++ - operator return value - d.cpp
↑ ↓ ← → mesti_mudam yahoo.com writes:
this is a dummy matrix algebra library example. to avoid matrix creation like
"Matrix a, b(a), c=a;" the copy-ctor is private. currently it compiles and runs
nicely. when the commented version of operator* is used, it doesnt compile and
give this error message:
OPTLINK (R) for Win32 Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved
d2.obj(d2)
Error 42: Symbol Undefined ??0Matrix AAE ABV0 Z (syscall Matrix::Matrix(Matrix
const &))
--- errorlevel 1
is this an error of dmc, or should i not try to make copy-ctor private?
↑ ↓ ← → Heinz Saathoff <newshsaat arcor.de> writes:
Hello,
this is a dummy matrix algebra library example. to avoid matrix creation like
"Matrix a, b(a), c=a;" the copy-ctor is private. currently it compiles and runs
nicely. when the commented version of operator* is used, it doesnt compile and
give this error message:
OPTLINK (R) for Win32 Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved
d2.obj(d2)
Error 42: Symbol Undefined ??0Matrix AAE ABV0 Z (syscall
Matrix::Matrix(Matrix
const &))
You return a Matrix-Object by value in both versions of 'operator*'. The
semantics say that the local Matrix-Object is copied to the function
result with the copy constructor. Therefore the copy constructor must be
accessible in both cases. The compiler is allowed to optimize the actual
copy away (constructing the local obkect directly in the return-object.
Therefore the message is correct, but IMO too late (the compiler should
detect this because the copy constructor isn't accessible). Even if the
compiler is allowed to optimize the copy the semantics of applying the
copy-constructor must be checked!
- Heinz
↑ ↓ ← → mesti_mudam yahoo.com writes:
well it is apparently return by value, but in reality it is not, or something in
between let's say.
in the current verison of the code, for c=a*b, the compiler allocates a temp
space in the caller and passes a pointer-to-that-temp-space to the operator*.
the res object in the uncommented version of operator* is not actually a local
object in operator*, its space was allocated in the caller, it is just
initialized in operator* with a constructor. note that the compiler can do this
because it knows in compile time that res will be the result.
in the uncommented version of operator*, the compiler cannot determine in
compile time which object will be returned, res or res2, so it chooses to do the
following:
again a temp space is allocated in the caller, and a pointer-to-that-temp-space
is passed to operator* (in fact this is always done). then according to the
result of the if statement, a 'local' object is created, res or res2, and then
the temp space is initialized with, not a constructor but, a copy constructor
where res or res2 is a parameter to that copy constructor.
the following is also possible:
instead, the temp space can be initiliazed, according to the result of if
statement, with (possibly) different constructors with (possibly) different
parameters and then operator* returns. there is no need to create local objects
and use a copy constructor (with a parameter of a local object) to initialize
the temp spcace.
thx
In article <MPG.1f26af1f11c95889989700 news.digitalmars.com>, Heinz Saathoff
says...
Hello,
this is a dummy matrix algebra library example. to avoid matrix creation like
"Matrix a, b(a), c=a;" the copy-ctor is private. currently it compiles and runs
nicely. when the commented version of operator* is used, it doesnt compile and
give this error message:
OPTLINK (R) for Win32 Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved
d2.obj(d2)
Error 42: Symbol Undefined ??0Matrix AAE ABV0 Z (syscall
Matrix::Matrix(Matrix
const &))
You return a Matrix-Object by value in both versions of 'operator*'. The
semantics say that the local Matrix-Object is copied to the function
result with the copy constructor. Therefore the copy constructor must be
accessible in both cases. The compiler is allowed to optimize the actual
copy away (constructing the local obkect directly in the return-object.
Therefore the message is correct, but IMO too late (the compiler should
detect this because the copy constructor isn't accessible). Even if the
compiler is allowed to optimize the copy the semantics of applying the
copy-constructor must be checked!
- Heinz
↑ ↓ ← → Heinz Saathoff <newshsaat arcor.de> writes:
Hello,
well it is apparently return by value, but in reality it is not, or something
in
between let's say.
Even if not implemented as 'copy by value' the semantics is 'copy the
local object to the function result with the copy-constructor'.
Therefore the copy constructor must be accessible!
in the current verison of the code, for c=a*b, the compiler allocates a temp
space in the caller and passes a pointer-to-that-temp-space to the operator*.
the res object in the uncommented version of operator* is not actually a local
object in operator*, its space was allocated in the caller, it is just
initialized in operator* with a constructor. note that the compiler can do this
because it knows in compile time that res will be the result.
This optimization is allowed by the standard DMC implements it.
Nonetheless, the compiler has to check accessibility as if this
optimization is not done. If the copy-constructor is private it must
give a error message.
in the uncommented version of operator*, the compiler cannot determine in
compile time which object will be returned, res or res2, so it chooses to do
the
following:
again a temp space is allocated in the caller, and a pointer-to-that-temp-space
is passed to operator* (in fact this is always done). then according to the
result of the if statement, a 'local' object is created, res or res2, and then
the temp space is initialized with, not a constructor but, a copy constructor
where res or res2 is a parameter to that copy constructor.
Ack. But in this case the copy-constructor is used even if
(semantically) unaccessible. Therefore the error-message should come
from the compiler and not from the linker!
the following is also possible:
instead, the temp space can be initiliazed, according to the result of if
statement, with (possibly) different constructors with (possibly) different
parameters and then operator* returns. there is no need to create local objects
and use a copy constructor (with a parameter of a local object) to initialize
the temp spcace.
But still the accessibility rules apply, even if the copy-constructor
call can be (and is allowed to be) optimized away.
- Heinz
↑ ↓ ← → mesti_mudam yahoo.com writes:
well what im saying is, if u r not using it, then its access rights doesnt
matter for u (compile it with -o -6). forcing something to be public which is
not used at all (in the current verison of code) is stupid, if the C++ standard
says it should be like that, then the standard is stupid. even in the 2nd
verison of operator* (with if), copy-ctor can be avoided and the code will be
better faster, and u still shouldnt need to make copy-ctor public. then when do
we need it? we need it only when we have to. and how does one prevent the user
from creating objects like "Matrix b(a), c=a;" which use copy-ctor. in fact
there r (should be) 2 kinds of copy-ctors. one which is called explicitly by the
programmer via something like "Matrix b(a), c=a;", and one that the compiler
uses for temp objects it creates.
In article <MPG.1f294e0fe5e8652d989701 news.digitalmars.com>, Heinz Saathoff
says...
Hello,
well it is apparently return by value, but in reality it is not, or something
in
between let's say.
Even if not implemented as 'copy by value' the semantics is 'copy the
local object to the function result with the copy-constructor'.
Therefore the copy constructor must be accessible!
in the current verison of the code, for c=a*b, the compiler allocates a temp
space in the caller and passes a pointer-to-that-temp-space to the operator*.
the res object in the uncommented version of operator* is not actually a local
object in operator*, its space was allocated in the caller, it is just
initialized in operator* with a constructor. note that the compiler can do this
because it knows in compile time that res will be the result.
This optimization is allowed by the standard DMC implements it.
Nonetheless, the compiler has to check accessibility as if this
optimization is not done. If the copy-constructor is private it must
give a error message.
in the uncommented version of operator*, the compiler cannot determine in
compile time which object will be returned, res or res2, so it chooses to do
the
following:
again a temp space is allocated in the caller, and a pointer-to-that-temp-space
is passed to operator* (in fact this is always done). then according to the
result of the if statement, a 'local' object is created, res or res2, and then
the temp space is initialized with, not a constructor but, a copy constructor
where res or res2 is a parameter to that copy constructor.
Ack. But in this case the copy-constructor is used even if
(semantically) unaccessible. Therefore the error-message should come
from the compiler and not from the linker!
the following is also possible:
instead, the temp space can be initiliazed, according to the result of if
statement, with (possibly) different constructors with (possibly) different
parameters and then operator* returns. there is no need to create local objects
and use a copy constructor (with a parameter of a local object) to initialize
the temp spcace.
But still the accessibility rules apply, even if the copy-constructor
call can be (and is allowed to be) optimized away.
- Heinz
↑ ↓ ← → Heinz Saathoff <newshsaat arcor.de> writes:
Hello,
well what im saying is, if u r not using it, then its access rights doesnt
matter for u (compile it with -o -6).
This is an _allowed_ optimization, that's what the standard says. A non-
optimizing compiler would use the copy constructor to copy the local
object to the returned object.
forcing something to be public which is
not used at all (in the current verison of code) is stupid, if the C++ standard
says it should be like that, then the standard is stupid.
The standard allows dumb compilers in code generation, but not in
sematic checks ;-)
even in the 2nd
verison of operator* (with if), copy-ctor can be avoided and the code will be
better faster, and u still shouldnt need to make copy-ctor public.
Allowed optimization, but a compiler is not forced to do so! Therefore
the constructor must be accessible!
then when do
we need it? we need it only when we have to. and how does one prevent the user
from creating objects like "Matrix b(a), c=a;" which use copy-ctor.
As far as I know the compiler is not allowed to optimize the copy
constructor away. It's only allowed for function return values.
in fact
there r (should be) 2 kinds of copy-ctors. one which is called explicitly by
the
programmer via something like "Matrix b(a), c=a;", and one that the compiler
uses for temp objects it creates.
Why should the programmer have to write two (most times) identical
constructors. I don't see a big benefit here.
- Heinz
|
|