Segmentation fault for lambda function in non-static data member initializer - c++

I am unsure about a possible GCC bug in initialization of a std::function from a lambda function capturing this in a non-static data member initializer. Is this allowed by the C++ standard or is this UB?
Given the following code:
#include <functional>
#include <iostream>
template <typename T>
struct A {
T x = 0;
std::function<void(T)> f = [this](T v) { x = v; };
};
int main() {
A<int> a;
a.f(1);
std::cout << a.x << "\n";
}
In my understanding, it should print 1. However, when built with GCC 5.4.0 or GCC 6.2.0, a.f(1) emits a segmentation fault, because the captured this pointer is null.
The following alternatives work as I expected:
Using constructor initializer list:
template <typename T>
struct B {
B() : f([this](T v) { x = v; }) {}
T x = 0;
std::function<void(T)> f;
};
Without template:
struct C {
int x = 0;
std::function<void(int)> f = [this](int v) { x = v; };
};
Also, when built with Clang 3.8.0, all three versions behave as I expect, which doesn't mean it is not UB.

You cannot do:
template <typename T>
struct A {
T x = 0;
std::function<void(T)> f = [this](T v) { x = v; };
};
As this does not exist when you define f. You need to initilize f in a constructor, such as:
A(){ f = [this](T v){ x=v; } }
It worked with G++4.8.

Your code compiles and runs on VS2015 (windows).
So this is probably a compiler error.
Also, if you will remove the template it works on http://cpp.sh/
Try this code:
#include <functional>
#include <iostream>
struct A {
int x = 0;
std::function<void(int)> f = [this](int v) { x = v; };
};
int main() {
A a;
a.f(1);
std::cout << a.x << "\n";
}
running original code on cpp.sh gives:
internal compiler error: in tsubst_copy, at cp/pt.c:12569
Please submit a full bug report
So I guess it's a bug

Related

How to define a lambda function inside a struct in c++

is there any possibility to have a lambda expression inside a struct in c++ . logic goes as follows.
struct alpha {
<lambda function> {
/* to do */
}
};
int main()
{
int a = //call the function inside the struct and compute.
}
You'll need to use std::function:
#include <iostream>
#include <functional>
struct Foo
{
const std::function<void()> hello = [] () { std::cout << "hello world!" << std::endl; };
};
int main()
{
Foo foo {};
foo.hello();
}
See live on Coliru.
It's unclear what you're asking exactly.
But a lambda, a.k.a. a functor, in C++ is mainly syntactic sugar for operator().
If you want to have a "callable" struct, you can just define operator() like this:
struct alpha {
int operator() () {
return 42;
}
};
int main()
{
alpha x;
int a = x();
std::cout << a << std::endl; // prints "42"
}
Yes, you can use std :: function to declare a pointer to a function, and when initializing the structure, substitute a function with the lambda pointer, for example
struct alpha{
std::function<int(int)>
};
...
alpha a{[](int a){return a;}};

callback in C++ struct

I have been trying to implement a callback function in c++. Within a class, I have a struct, a number of methods, and a method that creates an instance of the struct with one of the other methods as its argument.
The struct has many other variables, but an illustration is depicted here:
class MYCLASS
{
public:
MYCLASS();
struct TEST{
std::function<int(int)> foo;
};
int plus(int x){
return x + 1;
}
int minus(int x){
return x - 1;
}
void sim(){
TEST T; // make an instance of TEST
T.foo = plus(5); // assign TEST.foo a function (plus or minus)
T.foo(); // call the method we assigned
}
};
Within the sim method, I want to create an instance of test and give it either plus or minus, depending on some criterion. Both lines where I try and give the instance T a plus function and subsequently call it are incorrect.
If you want to delay the call to T.foo, then you could use a lambda like this:
T.foo = [this](int x) { return plus(x); };
T.foo(5);
Option - 1
If the member functions plus() and minus() are simple enough like you have shown, you can make them as lambda functions inside the struct TEST.
Since the capture-less lambdas can be stored in typed function pointers, the following will do what you want.
See live demo
#include <iostream>
class MYCLASS
{
int m_var = 5; // just for demonstration
public:
MYCLASS() = default;
struct TEST
{
using fPtrType = int(*)(int); // function pointer type
const fPtrType foo1 = [](int x) { return x + 1; }; // plus function
const fPtrType foo2 = [](int x) { return x - 1; }; // minus function
};
void sim()
{
TEST T;
std::cout << "Answer from int PLUS(int): " << T.foo1(m_var) << std::endl;
std::cout << "Answer from int MINUS(int): " << T.foo2(m_var) << std::endl;
}
};
Option - 2
If the above alter a lot in your code, use typed function pointer again for member functions and do as follows; which will avoid unnecessary copying(by capturing) the class instance to the lambda and template instantiation and other performance issues comes along with std::function as well.
See live demo
#include <iostream>
class MYCLASS
{
using fPtrType = int(MYCLASS::*)(int); // class member function pointer type
public:
MYCLASS() = default;
struct TEST { fPtrType foo = nullptr; };
int plus(int x) { return x + 1; }
int minus(int x) { return x - 1; }
void sim()
{
TEST T;
T.foo = &MYCLASS::plus; // now you can
std::cout << "Answer from int PLUS(int): " << (this->*T.MYCLASS::TEST::foo)(5) << std::endl;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ syntax would be a bit ugly
// later same ptr variable for minus()
T.foo = &MYCLASS::minus;
int answer = (this->*T.MYCLASS::TEST::foo)(5);
std::cout << "Answer from int MINUS(int): " << answer << std::endl;
}
};
int main()
{
MYCLASS obj;
obj.sim();
return 0;
}
Output:
Answer from int PLUS(int): 6
Answer from int MINUS(int): 4

clang - shared_ptr fails to run its deleter

This code prints 0 (with no optimization) or 666 (with optimizations turned on) when built with clang++ -std=c++11 (-O3 yields 666, which is what I would expect). When lambda is passed by universal reference the problem disappears.
FYI, GCC prints 666 on all the versions I've tested.
Is it a compiler bug or the code is incorrect?
#include <memory>
#include <iostream>
template <typename T>
std::shared_ptr<void> onScopeExit(T f)
{
return std::shared_ptr<void>((void*)1, [&](void *) {
f();
});
}
struct A {
void f() {
auto scopeGuard = onScopeExit([&]() { i = 666; }); // [1]
// ... (some work)
} // (lambda [1] being ? called on scope exit)
int i = 0;
};
A a;
int main() {
a.f();
std::cout << a.i << std::endl;
}
The compiler in question is:
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Your code has undefined behavior. You capture f by reference in onScopeExit but once you return the shared_ptr from the function the deleter is now holding a dangling reference to f, since f went out of scope. What you need to do is capture f by value, and then you won't have a dangling reference
template <typename T>
std::shared_ptr<void> onScopeExit(T f)
{
return std::shared_ptr<void>((void*)1, [=](void *) {
f();
});
}
struct A {
void f() {
auto scopeGuard = onScopeExit([&]() { i = 666; }); // [1]
// ... (some work)
} // (lambda [1] being ? called on scope exit)
int i = 0;
};
A a;
int main() {
a.f();
std::cout << a.i << std::endl;
}

g++ 4.8.2: could not convert from function pointer to std::function<>

I'm trying to write a class that takes, as a constructor parameter, a factory function that creates another instance of the same class on a transformed version of the input. For a trivial example, a functor class that takes an int, prints it, and returns another functor that prints the input's successor.
I'm getting errors of the form
error: could not convert 'foo' from 'Type(*)(int)' to 'std::function<Type(int)>'
The only seems to arise with factory functions passed into constructors.
Using a function pointer instead of a std::function<> works fine, but I was hoping that with C++11 I'd be able to avoid function pointers.
Here's an example:
#include <functional>
#include <iostream>
// std::function-returning-int param in ctor with default value
// This works fine
class PrInc; // "print and increment"
using Worker = std::function<int(int)>;
int foo(int i) {
std::cout << i << std::endl;
return i+1;
}
class PrInc {
public:
PrInc(int i, Worker fn = foo) : i_(i), fn_(fn) {}
int operator()() { return fn_(i_); }
private:
int i_;
Worker fn_;
};
// std::function-returning-PrInc2 param in ctor with default value
// This fails, at least on g++ 4.8.2 --std=c++11
class PrInc2;
using Factory = std::function<PrInc2(int)>;
// Use function ptrs (instead of std::function<>s) and it works fine
//typedef PrInc2 (*Factory)(int);
PrInc2 bar(int);
class PrInc2 {
public:
PrInc2(int i, Factory fn = bar) : i_(i), fn_(fn) {}
PrInc2 operator()() { return fn_(i_); }
private:
int i_;
Factory fn_;
};
PrInc2 bar(int i) {
std::cout << i << std::endl;
return PrInc2(i+1);
// error: could not convert 'bar' from 'PrInc2 (*)(int) to 'Factory {aka std::function<PrInc2(int)>'
}
int main() {
auto p1 = PrInc {1};
auto p2 = PrInc{p1()};
p2();
auto p3 = PrInc2 {1};
// error: could not convert 'bar' from 'PrInc2 (*)(int) to 'Factory {aka std::function<PrInc2(int)>'
auto p4 = p3();
p4();
return 0;
}
What am I doing wrong?
EDIT: thelink2012's suggestion to try PrInc2(int i, Factory fn = Factory(bar)) works fine on the "repro" above, but fails on the motivating example (GitHub link; relevant code is erdos.h:35-54 around ParseStep and ParseFunction). Back to the drawing board for a better repro....
The following part of your code, which is the only part that appears to be relevant to the compiler error you're asking about, compiles cleanly with gcc 4.9.2 using the -std=c++11 mode:
#include <functional>
#include <iostream>
using Worker = std::function<int(int)>;
int foo(int i) {
std::cout << i << std::endl;
return i+1;
}
class PrInc {
public:
PrInc(int i, Worker fn = foo) : i_(i), fn_(fn) {}
int operator()() { return fn_(i_); }
private:
int i_;
Worker fn_;
};
Most likely a bug in the older gcc you're using. Upgrade to a more recent version of gcc.

Code making SIGSEGV in GCC but not Clang

This code generates a SIGSEGV on runtime when compiled with GCC (4.7.2-5ubuntu) but not Clang (Apple LLVM 4.2)
#include <functional>
#include <iostream>
using FuncType = std::function<int(int)>;
int func(FuncType f, int i) {
return f(i)+1;
}
struct Alpha {
FuncType f, g;
Alpha(FuncType f) : f(f) {
g = [&](int i) -> int {
return func(f, i);
};
}
int go(int i) {
return g(i);
}
};
struct Beta {
int k = 0;
Beta newBeta(int nk) {
Beta beta = *this;
beta.k = nk;
return beta;
}
};
struct Gamma {
Beta beta;
void go(int j) {
auto f = [&](int i) -> int {
int n = beta.newBeta(i).k+j;
return n*n;
};
Alpha alpha(f);
std::cout << alpha.go(beta.k) << std::endl;
}
};
int main(int argc, char *argv[]) {
Gamma gamma;
gamma.go(7);
return 0;
}
Debugging, the crash occurs when the lambda f is called in func. beta reports as an invalid object, even though it should still be valid when the lambda is called.
It looks as though this is a result of this bug, but that bug was reportedly fixed in 4.7.2.
Edit: Initialized Beta::k for clarity, does not affect bug.
One problem is here:
Alpha(FuncType f) : f(f) {
g = [&](int i) -> int {
return func(f, i);
};
}
your lambda is binding f (an argument to the contructor and so local to the constructor) by reference, so after the constructor completes, that reference is dangling. When you later call g, you get undefined behavior as it refers to this dangling reference.
Change the [&] to [=] to bind by value and it should be ok.