I recently ran into some weird bugs due to this kind of code.
vector<int> a(a);
Why the code above is accepted? When is this necessary? And how to ask the compiler to forbid this kind of usage? Thank you.
I recently ran into some weird bugs due to this kind of code.
vector<int> a(a);
Why the code above is accepted? When is this necessary? And how to ask the compiler to forbid this kind of usage? Thank you.
The most common use case for that is actually in C, not C++ (you should not use malloc
in C++, although you can), but in this case C++ is backwards compatible:
mytype *p = malloc(sizeof *p);
By allowing the use of p
in the initializer expression, you can pass sizeof *p
to malloc
ensuring that whatever the size of mytype
is, the right size will be allocated. If you were not allowed to do *p
, then the expression above would have to have the type mytype
twice, and later maintenance in the code might update one of the types and fail to update the other.
This is an unusual construct to actually make use of, but it can be useful if a class has a constructor that takes a reference to some other object for some reason, and the caller may want to loop the object into its own initialization.
Here's a contrived example:
#include <iostream>
using namespace std;
struct PrintAnAddress {
PrintAnAddress()
: msg_("")
, addr_(NULL)
{ }
PrintAnAddress( char const *msg, PrintAnAddress const &that )
: msg_( msg )
, addr_( &that )
{ }
void operator()( ostream &os ) const {
cout << msg_ << addr_ << endl;
}
private:
char const *msg_;
PrintAnAddress const *addr_;
};
int main() {
PrintAnAddress p1;
PrintAnAddress p2( "p1:", p1 );
PrintAnAddress p3( "self:", p3 );
p1(cout);
p2(cout);
p3(cout);
}
When p2
is defined, it's set up to print the address of p1
, but when p3
is defined, it's set up to print its own address. If the p3
variable were not yet in scope, it would not be possible to refer to it in order to pass it in its initialization. (At least, not without instrumenting the class and somehow getting access to the this
pointer.)
I'm sure there are useful and valid applications of this construct, but as I say, it's pretty unusual, so none come to my mind at the moment.