c++ - operator return value - d.cpp
- mesti_mudam yahoo.com (41/41) Jul 13 2006 this is a dummy matrix algebra library example. to avoid matrix creation...
- Heinz Saathoff (12/23) Jul 18 2006 You return a Matrix-Object by value in both versions of 'operator*'. The...
- mesti_mudam yahoo.com (25/48) Jul 18 2006 well it is apparently return by value, but in reality it is not, or some...
- Heinz Saathoff (14/36) Jul 20 2006 Even if not implemented as 'copy by value' the semantics is 'copy the
- mesti_mudam yahoo.com (13/49) Jul 21 2006 well what im saying is, if u r not using it, then its access rights does...
- Heinz Saathoff (13/28) Jul 23 2006 This is an _allowed_ optimization, that's what the standard says. A non-
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? begin 0644 d.cpp M(VEN8VQU9&4 /&EO<W1R96%M/ T*=7-I;F< ;F%M97-P86-E('-T9#L-" T* M;G0 <VEZ93L-" E-871R:7 H8V]N<W0 36%T<FEX)BD[("\O=&\ <')E=F5N M="!M871R:7 8W)E871I;VX ;&EK92`B36%T<FEX(&$L(&(H82DL(&,]83LB M*3L-" E-871R:7 ;W!E<F%T;W(J*&-O;G-T($UA=')I>"8I.PT*?3L-" T* M:7, /#P 96YD;#L- M>#HZ36%T<FEX*&EN="!R+"!I;G0 8RD-"GL-" EC;W5T(#P\(")C=&]R:6D M(B`\/"!T:&ES(#P M<B`B(#P\('1H:7, /#P 96YD;#L-" ER;W=S/6-O;',]<VEZ93TP.PT*?0T* M*0T*>PT*"6-O=70 /#P (CUP87( (B`\/"`F;2`\/"!E;F1L.PT*"7)O=W,] M.PT*"6-O=70 /#P (BIR97, (B`\/"`F<F5S(#P M/"`F<F5S(#P ',#L-"GT-"BPS ` end
Jul 13 2006
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
Jul 18 2006
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
Jul 18 2006
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
Jul 20 2006
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
Jul 21 2006
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
Jul 23 2006