varargs lambda gives illegal instruction - bug in clang or UB? - c++

The following code gives Illegal instruction under clang, but works under gcc. Is it a bug in clang or is there some kind of UB?
#include <iostream>
#include <functional>
int main() {
std::function<void(const std::string&, const std::string&)> fn = [](...) { std::cout << "ok\n"; };
fn("a", "b");
}

As #Jarod42 commented, passing a non-trivial object to C-ellipsis has implementation defined semantics. Clang choose to abort in this case and it's normal.
To avoid the problem, one can use a lambda with a parameter pack like this:
#include <iostream>
#include <functional>
int main() {
std::function<void(const std::string&, const std::string&)> fn = [](auto&&...) { std::cout << "ok\n"; };
fn("a", "b");
}
It can be useful e.g. for default dummy callbacks:
constexpr auto DEFAULT_CALLBACK = [](auto&&...) {};

Related

error: passing 'const S' as 'this' argument discards qualifiers

Here is an simplified version of the problem from ported from large code base. I've solved the issue, but I don't like the way I solved it.
The problematic code that doesn't compile is this I'm starting with:
#include <iostream>
#include <cstdlib>
#include <vector>
#include <cassert>
#include <algorithm>
#include <cmath>
#include <array>
#include <utility>
#include <set>
#include <functional>
class S {
public:
int a;
int b;
mutable int c;
void set_c() { c = 222; }
};
struct cmp
{
bool operator()(const S& lhs, const S& rhs) const
{
return !(lhs.a == rhs.a && lhs.b == rhs.b);
}
};
class core {
public:
std::set<S, cmp> set_of_S;
std::function<void()> f;
void set_fn() {
f = [this]() {
auto it = set_of_S.begin();
it->set_c();
};
}
};
int main()
{
core core;
S a {.a = 2, .b = 3, .c = 0};
S b {.a = 2, .b = 3, .c = 0};
S c {.a = 2, .b = 4, .c = 0};
core.set_of_S.insert(a);
core.set_of_S.insert(b);
core.set_of_S.insert(c);
core.set_fn();
core.f();
std::cout << core.set_of_S.size() << '\n';
}
The compiler error is:
prog.cc: In lambda function:
prog.cc:37:23: error: passing 'const S' as 'this' argument discards qualifiers [-fpermissive]
it->set_c();
Ok, makes sense. As some people have told me, you should use the keyword mutable as this is not captured as a const and iterator it should be modifiable now (or atleast what I'm expecting):
void set_fn() {
f = [this]() mutable {
auto it = set_of_S.begin();
it->set_c();
};
}
This doesn't compile. This part doesn't make sense to me. So a member function cannot modify captured this inside lambda, but if you try to directly modify S::c inside the lambda compiler thinks that is okay. What? Doesn't make sense to me.
When I change:
void set_c() { c = 222; }
to
void set_c() const { c = 222; }
It will finally compile, but I don't like the solution, because we had to modify the original function signature just because the lambda won't accept it and it makes it less readable. I see lambdas as a tool and not something you have to design against. I have tried placing mutable keyword all over the place, but can't get it to compile. And I think there should be a way to permit member function to modify it's own state inside lambda.
Am I missing something or is this a compiler bug?
Here is the problematic code in wandbox: https://wandbox.org/permlink/qzFMW6WIRiKyY3Dj
I know this has been asked in: error: passing xxx as 'this' argument of xxx discards qualifiers but answers won't discuss on using mutable which to my understanding should solve these kind of situations.
Elements of a std::set<T> are unmodifiable - set_of_S.begin() returns a constant iterator: cppreference
Because both iterator and const_iterator are constant iterators (and may in fact be the same type), it is not possible to mutate the elements of the container through an iterator returned by any of these member functions [begin/cbegin].
That means that the element pointed to by the iterator it is const, so you can't call a non-const function such as set_c on it. it->c = 300 still works because you've made c mutable. It has nothing to do with the lambda you're calling this in being mutable or not.

can't assign std::bind return value to std::function

I have been trying to write a very simple piece of code but it doesn't seems to work and I am unable to make any sense out of the compiler error.
code:
#include <iostream>
#include <sstream>
#include <functional>
class c
{
public:
void test(std::stringstream ss){
std::cout<<ss.str()<<std::endl;
}
void test2(std::stringstream ss){
const auto bound=std::bind(&c::test,this, ss);
std::function<void()> f(bound);
f();
}
};
void test1(const std::stringstream ss){
std::cout<<ss.str()<<std::endl;
}
int main(){
std::stringstream ss;
ss<<"hello world";
//first
const auto bound=std::bind(&test1,ss);
std::function<void()> f(bound);
f();
//second
C obj;
obj.test2(ss);
return 0;
}
error:
bind.cpp:14:32: error: no matching function for call to ‘std::function<void()>::function(const std::_Bind<std::_Mem_fn<void (c::*)(std::__cxx11::basic_stringstream<char>)>(c*, std::__cxx11::basic_stringstream<char>)>&)’
std::function<void()> f(bound);
^
bind.cpp:30:31: error: no matching function for call to ‘std::function<void()>::function(const std::_Bind<void (*(std::__cxx11::basic_stringstream<char>))(std::__cxx11::basic_stringstream<char>)>&)’
std::function<void()> f(bound);
^
I am compiling with: g++ -std=c++14 bind.cpp.
I see here where the accepted answer suggested to use lambdas instead of std::bind but, can anybody tell why both first and second usage in the above code does not work?
The problems you are facing have to do with the fact that std::stringstream does not have a copy constructor.
The problems can be resolved by using const std::stringstream& as argument types instead of std::stringstream in couple of functions.
#include <iostream>
#include <sstream>
#include <functional>
class c
{
public:
// Change the argument to a const&
void test(std::stringstream const& ss){
std::cout<<ss.str()<<std::endl;
}
// Use std::cref to use a const& in the call to std::bind
void test2(std::stringstream ss){
const auto bound=std::bind(&c::test,this, std::cref(ss));
std::function<void()> f(bound);
f();
}
};
// Change the argument to a const&
void test1(const std::stringstream & ss){
std::cout<<ss.str()<<std::endl;
}
int main(){
std::stringstream ss;
ss<<"hello world";
//first
// Use std::cref to use a const& in the call to std::bind
const auto bound = std::bind(&test1, std::cref(ss));
std::function<void()> f = bound;
f();
return 0;
}

Deduction of auto doesn't work when implemented as Lambda. Error: before deduction of 'auto'

Here I've implemented a templated function and a templated Lambda. I've started exploring C++14 features and not sure what's wrong with the following lambda. Any suggestions?
#include <iostream>
#include <random>
#include <algorithm>
#include <functional>
template<class T = std::mt19937, std::size_t N = T::state_size>
auto MersenneEngine() {
return T(N);
}
template<class T = std::mt19937, std::size_t N = T::state_size>
auto MersenneEngineLambda = []() {
return T(N);
};
int main() {
// your code goes here
std::cout << MersenneEngine<std::mt19937>() << std::endl;
std::cout << MersenneEngineLambda<std::mt19937>() << std::endl; // Compilation error : error: use of 'MersenneEngineLambda<std::mersenne_twister_engine...before deduction of 'auto'
return 0;
}
Here's the complete code http://ideone.com/lveJRN
The code is fine.
You are witnessing a bug in your version of GCC (5.1). This is not highly surprising given that variable templates were brand new in GCC 5.
Empirically, it was fixed either in or before GCC 6.1.1.
Bug 67041 (and, more directly, its dupe bug 67350) looks potentially relevant.

std::forward Visual Studio 13 doesn't behave like I expect

I'm trying to learn some basic C++ 11, using Scott Meyers lecture on youtube called "An Effective C++11/14 Sampler"
https://www.youtube.com/watch?v=BezbcQIuCsY
Using his sample code for std::forward (min 19 in the lecture) I wrote the following code to understand the effect of std::forward
#include "stdafx.h"
#include <string>
#include <utility>
class A
{
public:
void Foo(std::string&& s)
{
std::string s2 = std::forward<std::string>(s);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
std::string s3 = "Hello World";
a.Foo(s3);
a.Foo("Hello World");
return 0;
}
Surprisingly it doesn't compile, a.Foo(s3) can't implicitly cast from lvalue to rvalue. So I changed a.Foo(s3); to a.Foo(std::move(s3)); Now it compiles.
However on both calls to Foo std::forward<std::string>(s); resolved to an rvalue and a Move operation occurred (s was reset to "" as its buffer was pilfered).
So I really don't understand what good is std::forward and when it does apply. What am I missing here?
Calling std::forward<> when template argument deduction / reference collapsing isn't involved doesn't make sense.
The point of forwarding references (which Scott Meyers used to call "universal references") is that, depending on the value category of what you're receiving, you can forward that value category as well.
But here, you're not confused at all as to what's the value category, it's static.
Here is a context that has template argument deduction:
template<typename T>
void f(T&& t) // T is to be deduced, && might be collapsed
{
g(std::forward<T>(t)); // will keep the category value
}
f(std::string{"hey"}); // T inferred std::string&&, so the parameter type is `std::string&& &&`, which is collapsed to `std::string &&`.
You need a forwarding reference:
#include <string>
#include <utility>
class A
{
public:
template <typename String>
void Foo(String&& s)
{
std::string s2 = std::forward<String>(s);
}
};
int main()
{
A a;
std::string s3 = "Hello World";
a.Foo(s3);
a.Foo("Hello World");
return 0;
}
live example

Returning result of std::bind

I've managed to figure out how to use std::bind to replace a whole bunch of code that previously triggered C-style callbacks (not shown here) via a web of static variables, static functions, and a compiler extension __closure.
This code compiles and runs successfully; however, in trying to make a slight improvement I get a weird compiler error.
#include <iostream>
#include <string>
#include <functional>
typedef void MyFunc(std::string &);
struct Master
{
void func(std::string &s) { std::cout << "Master::func(" << s << ")\n"; }
void go();
Master() {}
private:
Master(Master const &);
};
int main()
{
Master m;
m.go();
}
void call_function( std::function<MyFunc> fp, std::string s )
{
fp(s);
}
template<typename FuncT, typename Host>
typename std::function<FuncT> my_binder(Host *h, FuncT Host::*p)
{
using std::placeholders::_1;
return std::bind(p, h, _1);
}
void Master::go()
{
std::string s("hello");
// OK
using std::placeholders::_1;
std::function<MyFunc> f = std::bind(&Master::func, this, _1);
call_function(f, s);
call_function( std::bind(&Master::func, this, _1), s );
// Undefined structure 'boost::function<void(std::string &)>'
my_binder(this, &Master::func);
// I'm hoping to end up here
// call_function( my_binder(this, &Master::func), s );
}
The code appears to work in latest g++ and clang, but gives
// Undefined structure 'boost::function<void(std::string &)>'
on another compiler which has not-quite-c++11 support. Is my code correct (i.e. the failing compiler has a bug)?
Also: is there a pre-existing template I can use instead of my_binder? My aim is to make it so that people can call call_function as easily as possible, without having to muck around with including std::placeholders and so on. Of course this is possible with a preprocessor macro but it'd be nice to use a template function.