If i have an instance of std::function that is bound to a member function of an object instance and that object instance goes out of scope and is otherwise destroyed will my std::function object now be considered to be a bad pointer that will fail if called?
Example:
int main(int argc,const char* argv){
type* instance = new type();
std::function<foo(bar)> func = std::bind(type::func,instance);
delete instance;
func(0);//is this an invalid call
}
Is there something in the standard that specifies what should happen? My hunch is that it will throw and exception because the object no longer exists
EDIT:
Does the standard specify what should happen?
Is it undefined behavior?
EDIT 2:
#include <iostream>
#include <functional>
class foo{
public:
void bar(int i){
std::cout<<i<<std::endl;
}
};
int main(int argc, const char * argv[]) {
foo* bar = new foo();
std::function<void(int)> f = std::bind(&foo::bar, bar,std::placeholders::_1);
delete bar;
f(0);//calling the dead objects function? Shouldn't this throw an exception?
return 0;
}
Running this code i receive an output value of 0;
What will happen is undefined behavior.
The bind() call will return some object that contains a copy of instance, so that when you call func(0) will effectively call:
(instance->*(&type::func))(0);
Dereferencing an invalid pointer, as you would do there if instance were deleted, is undefined behavior. It will not throw an exception (although, it's undefined, so it could, who knows).
Note that you're missing a placeholder in your call:
std::function<foo(bar)> func =
std::bind(type::func, instance, std::placeholders::_1);
// ^^^^^^^ here ^^^^^^^^^
Without that, you can't call func(0) even with a non-deleted instance.
Updating your example code to better illustrate what's going on:
struct foo{
int f;
~foo() { f = 0; }
void bar(int i) {
std::cout << i+f << std::endl;
}
};
With that added destructor, you can see the difference between copying the pointer (in f) and copying the object that was pointed to (in g):
foo* bar = new foo{42};
std::function<void(int)> f = std::bind(&foo::bar, bar, std::placeholders::_1);
std::function<void(int)> g = std::bind(&foo::bar, *bar, std::placeholders::_1);
f(100); // prints 142
g(100); // prints 142
delete bar;
f(100); // prints 100
g(100); // prints 142 still, because it has a copy of
// the object bar pointed to, rather than a copy
// of the pointer
Related
This code below will result in memory loss because rA is initialized as invalid when it is constructed. When can I do to fix this problem?
Use shared_ptr or hope for future compiler versions to catch this bad code?
#include <memory>
using namespace std;
struct A {};
void use(const A& a) {};
unique_ptr<A> foo()
{
unique_ptr<A> pa(new A());
return pa;
}
int main()
{
const A& rA = *foo(); // rA is unusable, initialized with invalid reference (invalidated by destruction of temporary unique_ptr returned from foo)
use(rA);
}
Rewrite your main as:
int main()
{
auto a = foo();
use(*a);
}
As an aside I would rewrite foo as:
std::unique_ptr<A> foo()
{
return std::make_unique<A>();
}
When you return objects by value you return a temporary that will get destroyed immediately unless it is copied or bound to a variable from the caller's side.
What you are doing wrong is binding a reference to something the returned temporary object contains and not the returned object itself. By the time you access the thing you have bound a reference to it has been deleted by the temporary object's destructor when it was destroyed.
To illustrate what you are doing wrong I have written an equivalent example using a std::vector and binding a reference to one of its elements:
void use(const int& a) {}
std::vector<int> foo()
{
return {1, 2, 3};
}
int main()
{
const int& rA = foo()[0]; // bind to an element
// the vector itself is destroyed by the time we get here
use(rA); // whoops using a reference to an element from a destroyed vector
}
I've noticed that newer libraries have been deleting the copy constructors from their objects. These objects always require a bit of build-up, so I inevitably have them returned by a function.
But does this mean I'm expected to use pointer semantics after retrieving the object?
Example:
This won't work because the library's object has a deleted copy constructor.
#include <memory>
//fancy library object
struct Foo{
Foo(){}
Foo(Foo const& foo)=delete;
};
Foo Create_Foo(){
Foo f;
// ... customize f before returning ...
return f;
}
int main(){
auto f = Create_Foo();
}
It doesn't seem like I can move the object out of the function:
Foo&& Create_Foo(){
Foo f;
// ... customize f before returning ...
return std::move(f);
}
So I have no choice but to use pointer semantics now?
std::unique_ptr<Foo> Create_Foo(){
auto f = std::make_unique<Foo>();
// ... customize f before returning ...
return f;
}
Is there any way to avoid using pointers,
but still get the constructed object as the result of the function?
I'm not apposed to using pointers, as it's likely the efficient and correct thing to do, but I'm interested in knowing if this is something I'm forced to do when I want the constructed object as the result of the function.
You have declared copy constructor, thus compiler won't declare move constructor.
struct Foo{
Foo() {}
Foo(Foo&&) = default;
Foo(Foo const& foo) = delete;
};
Foo Create_Foo(){
Foo f;
// ... customize f before returning ...
return std::move(f);
}
int main() {
auto f = Create_Foo();
}
Here's some C++ code:
#include <iostream>
class A
{
int x;
int y;
double v;
public:
A(int x, int y)
:x(x),y(y)
{
std::cerr << "A("<<x<<","<<y<<")\n";
}
~A()
{
std::cerr << "~A()\n";
}
operator double* ()
{
v=1.5*x+y;
return &v;
}
};
void f(double* val)
{
std::cerr << "f("<<*val<<")\n";
*val=0.3;
}
int main()
{
f(A(3,5));
}
I get the following as output:
A(3,5)
f(9.5)
~A()
I.e. as I'd like it to work. But I'm not sure whether destructor of A must be called after f returns. Is it guaranteed? Can the pointer returned by operator double* () somehow become invalid in the call of f?
You are declaring an A object as an actual parameter of f, when you do that, for all effects the new object is like a local variable of f so ~A is guaranteed to be called at the end of f execution.
If f returns the address returned by operator double* () and it is used after f has returned you will be accessing to invalid memory. One way to avoid this situation is making double v static but you have to consider that, in your code, the A class created object only exits while f block is running.
The arguments to a function are evaluated before the function is invoked, and the temporaries will live to the end of the full expression that they are in. So yes, the instance of A will live to just past the end of the invocation of f.
For a class Foo, is there a way to disallow constructing it without giving it a name?
For example:
Foo("hi");
And only allow it if you give it a name, like the following?
Foo my_foo("hi");
The lifetime of the first one is just the statement, and the second one is the enclosing block. In my use case, Foo is measuring the time between constructor and destructor. Since I never refer to the local variable, I often forget to put it in, and accidentally change the lifetime. I'd like to get a compile time error instead.
Another macro-based solution:
#define Foo class Foo
The statement Foo("hi"); expands to class Foo("hi");, which is ill-formed; but Foo a("hi") expands to class Foo a("hi"), which is correct.
This has the advantage that it is both source- and binary-compatible with existing (correct) code. (This claim is not entirely correct - please see Johannes Schaub's Comment and ensuing discussion below: "How can you know that it is source compatible with existing code? His friend includes his header and has void f() { int Foo = 0; } which previously compiled fine and now miscompiles! Also, every line that defines a member function of class Foo fails: void class Foo::bar() {}")
How about a little hack
class Foo
{
public:
Foo (const char*) {}
};
void Foo (float);
int main ()
{
Foo ("hello"); // error
class Foo a("hi"); // OK
return 1;
}
Make the constructor private but give the class a create method.
This one doesn't result in a compiler error, but a runtime error. Instead of measuring a wrong time, you get an exception which may be acceptable too.
Any constructor you want to guard needs a default argument on which set(guard) is called.
struct Guard {
Guard()
:guardflagp()
{ }
~Guard() {
assert(guardflagp && "Forgot to call guard?");
*guardflagp = 0;
}
void *set(Guard const *&guardflag) {
if(guardflagp) {
*guardflagp = 0;
}
guardflagp = &guardflag;
*guardflagp = this;
}
private:
Guard const **guardflagp;
};
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
The characteristics are:
Foo f() {
// OK (no temporary)
Foo f1("hello");
// may throw (may introduce a temporary on behalf of the compiler)
Foo f2 = "hello";
// may throw (introduces a temporary that may be optimized away
Foo f3 = Foo("hello");
// OK (no temporary)
Foo f4{"hello"};
// OK (no temporary)
Foo f = { "hello" };
// always throws
Foo("hello");
// OK (normal copy)
return f;
// may throw (may introduce a temporary on behalf of the compiler)
return "hello";
// OK (initialized temporary lives longer than its initializers)
return { "hello" };
}
int main() {
// OK (it's f that created the temporary in its body)
f();
// OK (normal copy)
Foo g1(f());
// OK (normal copy)
Foo g2 = f();
}
The case of f2, f3 and the return of "hello" may not be wanted. To prevent throwing, you can allow the source of a copy to be a temporary, by resetting the guard to now guard us instead of the source of the copy. Now you also see why we used the pointers above - it allows us to be flexible.
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
Foo(Foo &&other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
Foo(const Foo& other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
The characteristics for f2, f3 and for return "hello" are now always // OK.
A few years ago I wrote a patch for the GNU C++ compiler which adds a new warning option for that situation. This is tracked in a Bugzilla item.
Unfortunately, GCC Bugzilla is a burial ground where well-considered patch-included feature suggestions go to die. :)
This was motivated by the desire to catch exactly the sort of bugs that are the subject of this question in code which uses local objects as gadgets for locking and unlocking, measuring execution time and so forth.
As is, with your implementation, you cannot do this, but you can use this rule to your advantage:
Temporary objects cannot be bound to non-const references
You can move the code from the class to an freestanding function which takes a non-const reference parameter. If you do so, You will get a compiler error if an temporary tries to bind to the non-const reference.
Code Sample
class Foo
{
public:
Foo(const char* ){}
friend void InitMethod(Foo& obj);
};
void InitMethod(Foo& obj){}
int main()
{
Foo myVar("InitMe");
InitMethod(myVar); //Works
InitMethod("InitMe"); //Does not work
return 0;
}
Output
prog.cpp: In function ‘int main()’:
prog.cpp:13: error: invalid initialization of non-const reference of type ‘Foo&’ from a temporary of type ‘const char*’
prog.cpp:7: error: in passing argument 1 of ‘void InitMethod(Foo&)’
Simply don't have a default constructor, and do require a reference to an instance in every constructor.
#include <iostream>
using namespace std;
enum SelfRef { selfRef };
struct S
{
S( SelfRef, S const & ) {}
};
int main()
{
S a( selfRef, a );
}
No, I'm afraid this isn't possible. But you could get the same effect by creating a macro.
#define FOO(x) Foo _foo(x)
With this in place, you can just write FOO(x) instead of Foo my_foo(x).
Since the primary goal is to prevent bugs, consider this:
struct Foo
{
Foo( const char* ) { /* ... */ }
};
enum { Foo };
int main()
{
struct Foo foo( "hi" ); // OK
struct Foo( "hi" ); // fail
Foo foo( "hi" ); // fail
Foo( "hi" ); // fail
}
That way you can't forget to name the variable and you can't forget to write struct. Verbose, but safe.
Declare one-parametric constructor as explicit and nobody will ever create an object of that class unintentionally.
For example
class Foo
{
public:
explicit Foo(const char*);
};
void fun(const Foo&);
can only be used this way
void g() {
Foo a("text");
fun(a);
}
but never this way (through a temporary on the stack)
void g() {
fun("text");
}
See also: Alexandrescu, C++ Coding Standards, Item 40.
For a class Foo, is there a way to disallow constructing it without giving it a name?
For example:
Foo("hi");
And only allow it if you give it a name, like the following?
Foo my_foo("hi");
The lifetime of the first one is just the statement, and the second one is the enclosing block. In my use case, Foo is measuring the time between constructor and destructor. Since I never refer to the local variable, I often forget to put it in, and accidentally change the lifetime. I'd like to get a compile time error instead.
Another macro-based solution:
#define Foo class Foo
The statement Foo("hi"); expands to class Foo("hi");, which is ill-formed; but Foo a("hi") expands to class Foo a("hi"), which is correct.
This has the advantage that it is both source- and binary-compatible with existing (correct) code. (This claim is not entirely correct - please see Johannes Schaub's Comment and ensuing discussion below: "How can you know that it is source compatible with existing code? His friend includes his header and has void f() { int Foo = 0; } which previously compiled fine and now miscompiles! Also, every line that defines a member function of class Foo fails: void class Foo::bar() {}")
How about a little hack
class Foo
{
public:
Foo (const char*) {}
};
void Foo (float);
int main ()
{
Foo ("hello"); // error
class Foo a("hi"); // OK
return 1;
}
Make the constructor private but give the class a create method.
This one doesn't result in a compiler error, but a runtime error. Instead of measuring a wrong time, you get an exception which may be acceptable too.
Any constructor you want to guard needs a default argument on which set(guard) is called.
struct Guard {
Guard()
:guardflagp()
{ }
~Guard() {
assert(guardflagp && "Forgot to call guard?");
*guardflagp = 0;
}
void *set(Guard const *&guardflag) {
if(guardflagp) {
*guardflagp = 0;
}
guardflagp = &guardflag;
*guardflagp = this;
}
private:
Guard const **guardflagp;
};
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
The characteristics are:
Foo f() {
// OK (no temporary)
Foo f1("hello");
// may throw (may introduce a temporary on behalf of the compiler)
Foo f2 = "hello";
// may throw (introduces a temporary that may be optimized away
Foo f3 = Foo("hello");
// OK (no temporary)
Foo f4{"hello"};
// OK (no temporary)
Foo f = { "hello" };
// always throws
Foo("hello");
// OK (normal copy)
return f;
// may throw (may introduce a temporary on behalf of the compiler)
return "hello";
// OK (initialized temporary lives longer than its initializers)
return { "hello" };
}
int main() {
// OK (it's f that created the temporary in its body)
f();
// OK (normal copy)
Foo g1(f());
// OK (normal copy)
Foo g2 = f();
}
The case of f2, f3 and the return of "hello" may not be wanted. To prevent throwing, you can allow the source of a copy to be a temporary, by resetting the guard to now guard us instead of the source of the copy. Now you also see why we used the pointers above - it allows us to be flexible.
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
Foo(Foo &&other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
Foo(const Foo& other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
The characteristics for f2, f3 and for return "hello" are now always // OK.
A few years ago I wrote a patch for the GNU C++ compiler which adds a new warning option for that situation. This is tracked in a Bugzilla item.
Unfortunately, GCC Bugzilla is a burial ground where well-considered patch-included feature suggestions go to die. :)
This was motivated by the desire to catch exactly the sort of bugs that are the subject of this question in code which uses local objects as gadgets for locking and unlocking, measuring execution time and so forth.
As is, with your implementation, you cannot do this, but you can use this rule to your advantage:
Temporary objects cannot be bound to non-const references
You can move the code from the class to an freestanding function which takes a non-const reference parameter. If you do so, You will get a compiler error if an temporary tries to bind to the non-const reference.
Code Sample
class Foo
{
public:
Foo(const char* ){}
friend void InitMethod(Foo& obj);
};
void InitMethod(Foo& obj){}
int main()
{
Foo myVar("InitMe");
InitMethod(myVar); //Works
InitMethod("InitMe"); //Does not work
return 0;
}
Output
prog.cpp: In function ‘int main()’:
prog.cpp:13: error: invalid initialization of non-const reference of type ‘Foo&’ from a temporary of type ‘const char*’
prog.cpp:7: error: in passing argument 1 of ‘void InitMethod(Foo&)’
Simply don't have a default constructor, and do require a reference to an instance in every constructor.
#include <iostream>
using namespace std;
enum SelfRef { selfRef };
struct S
{
S( SelfRef, S const & ) {}
};
int main()
{
S a( selfRef, a );
}
No, I'm afraid this isn't possible. But you could get the same effect by creating a macro.
#define FOO(x) Foo _foo(x)
With this in place, you can just write FOO(x) instead of Foo my_foo(x).
Since the primary goal is to prevent bugs, consider this:
struct Foo
{
Foo( const char* ) { /* ... */ }
};
enum { Foo };
int main()
{
struct Foo foo( "hi" ); // OK
struct Foo( "hi" ); // fail
Foo foo( "hi" ); // fail
Foo( "hi" ); // fail
}
That way you can't forget to name the variable and you can't forget to write struct. Verbose, but safe.
Declare one-parametric constructor as explicit and nobody will ever create an object of that class unintentionally.
For example
class Foo
{
public:
explicit Foo(const char*);
};
void fun(const Foo&);
can only be used this way
void g() {
Foo a("text");
fun(a);
}
but never this way (through a temporary on the stack)
void g() {
fun("text");
}
See also: Alexandrescu, C++ Coding Standards, Item 40.