Below code fails with BAD_ACCESS when I call s_capture_void_int() in the last line and I do not understand why. I suppose that when I assign lambda expression to a global variable it supposed to copy itself together with captured values. So in my understanding dangling references should not appear. But it looks like I'm missing something.
std::function<void()> s_capture_void_int;
void capture_void_int (const std::function<void(int)>& param)
{
s_capture_void_int = [param]() {
param(1);
};
}
void capture_local_lambda()
{
auto local_lambda = [](int) {
};
s_capture_void_int = [local_lambda]() {
local_lambda(1);
};
}
BOOST_AUTO_TEST_CASE( test_lambda_captures )
{
//Case 1: this works
auto func2 = [](int){};
{
std::function<void(int)> func2_fn(func2);
s_capture_void_int = [func2_fn]() { func2_fn(1); };
}
s_capture_void_int();
//case 2: even this works.
capture_local_lambda();
s_capture_void_int();
//case 3: but this fails.
auto func3 = [](int){};
{
std::function<void(int)> func3_fn(func3);
capture_void_int(func3_fn);
}
s_capture_void_int(); //<- it crashes here
}
I don't understand two things here:
If crash happen because of func3_fn goes out of scope then why case 1
and 2 works?
If I change this code to std::function (note no parameter) then it works ok. Could it be a compiler bug?
For anybody who come across same problem. This is indeed a compiler bug and I found simple and stupid workaround. Workaround is not tested but at least my program does not segfault right away on a first call to std::function.
Problem manifest itself with clang shipped with Xcode 5.0.2 and 5.1 compiler. gcc 4.8 and possibly stock clang does not have this problem. Simplest possible program to trigger problem:
#include <iostream>
#include <functional>
std::function<void()> buggy_function;
/*
void workaround (const std::function<void(int)>& param)
{
auto a = [&,param]() {
param(1);
};
}
*/
void trigger_bug (const std::function<void(int)>& param)
{
buggy_function = [&,param]() {
param(1);
};
}
int main(int argc, const char * argv[])
{
auto func3 = [](int){};
std::function<void(int)> func3_fn(func3);
trigger_bug(func3_fn);
buggy_function();
return 0;
}
If you uncomment 'workaround' function it magically start working. Order of functions is important, workaround function have to be before any other functions using std::function. If you put 'workaround' below 'trigger_bug' then it stop working.
I'd say it's a compiler bug. It works fine in GCC. Perhaps the param in capture_void_int is incorrectly captured by reference (since it's a reference) when it should instead be captured by value.
Related
I have a simple class:
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- Ambiguity is here! I want to call 'void f()'
}
I want to resolve ambiguity of a method call in favour of the exception-throwing method by any means.
The rationale behind such interface:
To have the noexcept(true) and noexcept(false) interface,
To allow optionally get extra information via a pointer in the noexcept(false) variant - while the noexcept(true) variant will always pack this information inside an exception.
Is it possible at all? Suggestions for a better interface are also welcome.
Having functions with this kind of signatures is obviously a bad design as you've found out. The real solutions are to have different names for them or to lose the default argument and were presented already in other answers.
However if you are stuck with an interface you can't change or just for the fun of it here is how you can explicitly call void f():
The trick is to use function pointer casting to resolve the ambiguity:
a.f(); // <- ambiguity is here! I want to call 'void f()'
(a.*(static_cast<void (A::*)()>(&A::f)))(); // yep... that's the syntax... yeah...
Ok, so it works, but don't ever write code like this!
There are ways to make it more readable.
Use a pointer:
// create a method pointer:
auto f_void = static_cast<void (A::*)()>(&A::f);
// the call is much much better, but still not as simple as `a.f()`
(a.*f_void)();
Create a lambda or a free function
auto f_void = [] (A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
// or
void f_void(A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
f_void(a);
I don't know if this is necessary better. The call syntax is definitely simpler, but it might be confusing as we are switching from a method call syntax to a free function call syntax.
Both versions f have different meanings.
They should have two different name, as:
f for the throwing one, because using it means that your are confident on success, and failure would be an exception in the program.
try_f() or tryF() for the error-return based one, because using it means that failure of the call is an expected outcome.
Two different meanings should be reflected in the design with two different name.
Because it seems fundamentally obvious to me, I may be missing something or may not fully understand your question. However, I think this does exactly what you want:
#include <utility>
class A {
public:
bool f(int* status) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- now calls 'void f()'
a.f(nullptr); // calls 'bool f(int *)'
}
I simply removed the default argument from the noexcept variant. It's still possible to call the noexcept variant by passing nullptr as an argument, which seems a perfectly fine way of indicating that you want to call that particular variant of the function - after all, there's going to have to be some syntactic marker indicating which variant you want to call!
I agree with other users' suggestions to simply remove the default argument.
A strong argument in favour of such a design is that it would be in line with the new C++17 filesystem library, whose functions typically offer callers the choice between exceptions and error reference parameters.
See for example std::filesystem::file_size, which has two overloads, one of them being noexcept:
std::uintmax_t file_size( const std::filesystem::path& p );
std::uintmax_t file_size( const std::filesystem::path& p,
std::error_code& ec ) noexcept;
The idea behind this design (which is originally from Boost.Filesystem) is almost identical to yours, except of the default argument. Remove it and you do it like a brand new component of the standard library, which obviously can be expected not to have a completely broken design.
In C++14 it's ambiguous because noexcept is not part of the function signature. With that said...
You have a very strange interface. Although f(int* status = nullptr) is labelled noexcept, because it has a twin that does throw a exception, you are not really giving the caller a logical exception guarantee. It seems you simultaneously want f to always succeed while throwing an exception if the precondition is not met (status has a valid value, i.e not nullptr). But if f throws, what state is the object in? You see, your code is very hard to reason about.
I recommend you take a look at std::optional instead. It'll signal to the reader what you are actually trying to do.
C++ already has a type specifically used as an argument to disambiguate between throwing and non-throwing variants of a function: std::nothrow_t. You can use that.
#include <new>
class A {
public:
bool f(std::nothrow_t, int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // Calls 'void f()'
a.f(std::nothrow); // Calls 'void f(std::nothrow_t, int*)'
}
Though I would still prefer an interface where the name distinguishes the variants, or possibly one where the distinction isn't necessary.
Here's a purely compile-time method.
It may be useful if your compiler happens to have trouble optimizing away function pointer calls.
#include <utility>
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
template<void (A::*F)()>
struct NullaryFunction {
static void invoke(A &obj) {
return (obj.*F)();
}
};
int main() {
A a;
// a.f(); // <- Ambiguity is here! I want to call 'void f()'
NullaryFunction<&A::f>::invoke(a);
}
So you are trying to throw an exception if the code is unprepared for an error return?
Then, how about
class ret
{
bool success;
mutable bool checked;
int code;
public:
ret(bool success, int code) : success(success), checked(false), code(code) { }
~ret() { if(!checked) if(!success) throw code; }
operator void *() const { checked = true; return reinterpret_cast<void *>(success); }
bool operator!() const { checked = true; return !success; }
int code() const { return code; }
};
This is still an Abomination unto Nuggan though.
By removing the if(!success) check in the destructor, you can make the code throw whenever a return code is not looked at.
I'm having issues with getting a partially-qualified function object to call later, with variable arguments, in another thread.
In GCC, I've been using a macro and typedef I made but I'm finishing up my project an trying to clear up warnings.
#define Function_Cast(func_ref) (SubscriptionFunction*) func_ref
typedef void(SubscriptionFunction(void*, std::shared_ptr<void>));
Using the Function_Cast macro like below results in "warning: casting between pointer-to-function and pointer-to-object is conditionally-supported"
Subscriber* init_subscriber = new Subscriber(this, Function_Cast(&BaseLoaderStaticInit::init), false);
All I really need is a pointer that I can make a std::bind<function_type> object of. How is this usually done?
Also, this conditionally-supported thing is really annoying. I know that on x86 my code will work fine and I'm aware of the limitations of relying on that sizeof(void*) == sizeof(this*) for all this*.
Also, is there a way to make clang treat function pointers like data pointers so that my code will compile? I'm interested to see how bad it fails (if it does).
Relevant Code:
#define Function_Cast(func_ref) (SubscriptionFunction*) func_ref
typedef void(SubscriptionFunction(void*, std::shared_ptr<void>));
typedef void(CallTypeFunction(std::shared_ptr<void>));
Subscriber(void* owner, SubscriptionFunction* func, bool serialized = true) {
this->_owner = owner;
this->_serialized = serialized;
this->method = func;
call = std::bind(&Subscriber::_std_call, this, std::placeholders::_1);
}
void _std_call(std::shared_ptr<void> arg) { method(_owner, arg); }
The problem here is that you are trying to use a member-function pointer in place of a function pointer, because you know that, under-the-hood, it is often implemented as function(this, ...).
struct S {
void f() {}
};
using fn_ptr = void(*)(S*);
void call(S* s, fn_ptr fn)
{
fn(s);
delete s;
}
int main() {
call(new S, (fn_ptr)&S::f);
}
http://ideone.com/fork/LJiohQ
But there's no guarantee this will actually work and obvious cases (virtual functions) where it probably won't.
Member functions are intended to be passed like this:
void call(S* s, void (S::*fn)())
and invoked like this:
(s->*fn)();
http://ideone.com/bJU5lx
How people work around this when they want to support different types is to use a trampoline, which is a non-member function. You can do this with either a static [member] function or a lambda:
auto sub = new Subscriber(this, [](auto* s){ s->init(); });
or if you'd like type safety at your call site, a templated constructor:
template<typename T>
Subscriber(T* t, void(T::*fn)(), bool x);
http://ideone.com/lECOp6
If your Subscriber constructor takes a std::function<void(void))> rather than a function pointer you can pass a capturing lambda and eliminate the need to take a void*:
new Subscriber([this](){ init(); }, false);
it's normally done something like this:
#include <functional>
#include <memory>
struct subscription
{
// RAII unsubscribe stuff in destructor here....
};
struct subscribable
{
subscription subscribe(std::function<void()> closure, std::weak_ptr<void> sentinel)
{
// perform the subscription
return subscription {
// some id so you can unsubscribe;
};
}
//
//
void notify_subscriber(std::function<void()> const& closure,
std::weak_ptr<void> const & sentinel)
{
if (auto locked = sentinel.lock())
{
closure();
}
}
};
The following code is a signal implementation copied from APUE with a little modification
namespace
{
using signal_handler = void (*)(int);
signal_handler signal(sigset_t sig, signal_handler);
}
Signal::signal_handler Signal::signal(sigset_t sig, void (*handler)(int))
{
struct sigaction newAction, oldAction;
sigemptyset(&newAction.sa_mask);
newAction.sa_flags = 0;
newAction.sa_handler = handler;
if (sig == SIGALRM)
{
#ifdef SA_INTERRUPT
newAction.sa_flags |= SA_INTERRUPT;
#endif
}
else
{
newAction.sa_flags |= SA_RESTART;
}
if (sigaction(sig, &newAction, &oldAction) < 0)
throw std::runtime_error("signal error: cannot set a new signal handler.")
return oldAction.sa_handler;
}
The above code works fine during my test, but I wanted to make it more like a C++ code, so I changed signal_handler alias to
using signal_handler = std::function<void (int)>;
and also I use
newAction.sa_handler = handler.target<void (int)>();
to replace
newAction.sa_handler = handler;
and now there is a problem. I find newAction.sa_handler is still NULL after
newAction.sa_handler = handler.target<void (int)>();
but I don't know why. Anyone can help me explain this? thanks.
Here is my test code:
void usr1_handler(int sig)
{
std::cout << "SIGUSR1 happens" << std::endl;
}
void Signal::signal_test()
{
try
{
Signal::signal(SIGUSR1, usr1_handler);
}
catch (std::runtime_error &err)
{
std::cout << err.what();
return;
}
raise(SIGUSR1);
}
Even when using the original code when I run it in Xcode, there is no output. Instead, I run the executable file manually, I can see SIGUSR1 happens in the terminal. Why? How can I see the output using Xcode?
The direct answer is that target() is very picky - you must name the type of the target exactly to get a pointer to it, otherwise you get a null pointer. When you set your signal to usr1_handler, that is a pointer to a function (not a function) - its type is void(*)(int), not void(int). So you're simply giving the wrong type to target(). If you change:
handler.target<void (int)>();
to
handler.target<void(*)(int)>();
that would give you the correct target.
But note what target() actually returns:
template< class T >
T* target();
It returns a pointer to the provided type - in this case that would be a void(**)(int). You'd need to dereference that before doing further assignment. Something like:
void(**p)(int) = handler.target<void(*)(int)>();
if (!p) {
// some error handling
}
newAction.sa_handler = *p;
Demo.
However, the real answer is that this makes little sense to do. std::function<Sig> is a type erased callable for the given Sig - it can be a pointer to a function, a pointer to a member function, or even a wrapped function object of arbitrary size. It is a very generic solution. But sigaction doesn't accept just any kind of generic callable - it accepts specifically a void(*)(int).
By creating a signature of:
std::function<void(int)> signal(sigset_t sig, std::function<void(int)> );
you are creating the illusion that you are allowing any callable! So, I might try to pass something like:
struct X {
void handler(int ) { ... }
};
X x;
signal(SIGUSR1, [&x](int s){ x.handler(s); });
That's allowed by your signature - I'm providing a callable that takes an int. But that callable isn't convertible to a function pointer, so it's not something that you can pass into sigaction(), so this is just erroneous code that can never work - this is a guaranteed runtime failure.
Even worse, I might pass something that is convertible to a function pointer, but may not know that that's what you need, so I give you the wrong thing:
// this will not work, since it's not a function pointer
signal(SIGUSR1, [](int s){ std::cout << s; });
// but this would have, if only I knew I had to do it
signal(SIGUSR1, +[](int s){ std::cout << s; });
Since sigaction() limits you to just function pointers, you should limit your interface to it to just function pointers. Strongly prefer what you had before. Use the type system to catch errors - only use type erasure when it makes sense.
Here you a little example that will help you to understand the mechanims.
#include <iostream>
#include <string>
#include <functional>
void printMyInt(int a)
{
std::cout << "This is your int " << a;
}
int main()
{
std::function<void(int)> f = printMyInt;
void (*const*foo)(int) = f.target<void(*)(int)>();
(*foo)(56);
}
I have simplified the code to the smallest sample that still has the problem. This code should print "42", but instead prints a different number. I also print the address of the "Secret" object in the destructor, and when it is accessed, to show that it is being destructed too early. Am I doing something wrong here, or could this be a problem with the compiler?
Code:
#include <iostream>
using namespace std;
struct Secret{
int value;
Secret(int value):value(value){}
~Secret(){
cout<<"destructor:"<<(void*)this<<endl;
value=0;
}
};
template<class Func>
class Copier{
public:
Func func;
Copier(Func func):func(func){}
void run(){
func();
}
auto copy(){
auto output = [this](){
func();
};
Copier<decltype(output)> out(output);
return out;
}
};
auto makeSecretPrinter(){
Secret secret(42);
auto secretPrinter = [secret](){
cout<<"reading object at address:"<<(void*)&secret<<endl;
cout<<"the secret is:"<<secret.value<<endl;
};
return Copier<decltype(secretPrinter)>(secretPrinter).copy();
}
int main(){
makeSecretPrinter().run();
return 0;
}
clang (version 3.5-1ubuntu1) output:
destructor:0x7fff9e3f9940
destructor:0x7fff9e3f9938
destructor:0x7fff9e3f9948
destructor:0x7fff9e3f9950
reading object at address:0x7fff9e3f9940
the secret is:0
GCC (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2 output:
destructor:0x7fff374facc0
destructor:0x7fff374facb0
destructor:0x7fff374faca0
destructor:0x7fff374fac90
reading object at address:0x7fff374facc0
the secret is:-1711045632
capturing this captures with pointer semantics. Changing this:
auto output = [this](){
func();
};
to this fixes the problem:
auto output = [self=*this](){
self.func();
};
The line: makeSecretPrinter().run(), it actually execute makeSecretPrinter() first, and then execute run(). However, when run() is executing, it's already out of the scope of makeSecretPrinter(). Thus the lambda function does not get correct value as the parameter to call.
Note that your class is receiving the function pointer only (or function reference, they are the same in semantics.) This means the value is not passed into the Copier class. When Copier tries to 'run()', it needs to pickup the variable in makeSecretPrinter(). However, as I said, it's out of scope at the time when 'run()' is to be executed.
Browsing some internet board I encountered this little challenge:
"Implement a recursive anonymous function in your favorite language"
Obviously this is easy using a std::function/function pointer.
What I'm really interested in is if this is possible without binding the lambda to an identifier?
Something like (ignoring the obvious infinite recursion):
[](){ this(); }();
Of course, in C++, to call any function you have to bind it to an identifier somewhere, simply owing to syntax constraints. But, if you will accept parameters as being sufficiently unnamed, then it is possible to create a version of the y-combinator in C++ which recurses nicely without being "named".
Now, this is really ugly because I don't know how to do a typedef for a recursive lambda. So it just uses a lot of cast abuse. But, it works, and prints FLY!! until it segfaults due to stack overflow.
#include <iostream>
typedef void(*f0)();
typedef void(*f)(f0);
int main() {
[](f x) {
x((f0)x);
} ([](f0 x) {
std::cout<<"FLY!!\n";
((f)x)(x);
});
}
The two lambdas are unnamed in the sense that neither is explicitly assigned to name anywhere. The second lambda is the real workhorse, and it basically calls itself by using the first lambda to obtain a reference to itself in the form of the parameter.
Here's how you would use this to do some "useful" work:
#include <iostream>
typedef int param_t;
typedef int ret_t;
typedef void(*f0)();
typedef ret_t(*f)(f0, param_t);
int main() {
/* Compute factorial recursively */
std::cout << [](f x, param_t y) {
return x((f0)x, y);
} ([](f0 x, param_t y) {
if(y == 0)
return 1;
return y*((f)x)(x, y-1);
}, 10) << std::endl;
}
Are you allowed to cheat?
void f(){
[]{ f(); }();
}
It's recursive - indirectly, atleast.
Otherwise, no, there is no way to refer to the lambda itself without assigning it a name.
No identifier for functions/methods, Close enough or not !?
struct A
{
void operator()()
{
[&]()
{
(*this)();
}();
}
};
To call
A{}(); // Thanks MooningDuck
I seem to have come up with a solution of my own:
#include <iostream>
int main()
{
std::cout<<"Main\n";
[&](){
std::cout<<"Hello!\n";
(&main+13)();
}();
}
First call to cout is present just to show that it's not calling main.
I came up with the 13 offset by trial and error, if anyone could explain why it's this value it would be great.