I got a segmentation fault for this code in GCC but compiles fine with MSVC
QMap<int, QPair<QString, QString>> someData;
// inserting some value
for (auto id : someData.keys()) {
auto [foo, bar] = someData[id];
//do stuff with foo, bar.
}
And the structured binding emits a segfault.
Log:
internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-7/README.Bugs> for instructions.
Solution
declare the structured binding as reference.
auto& [foo, bar] = someData[id];
It looks like GCC cannot deduce the qualifiers, since operator[] returns a T&.
Related
I'm using C++14 with protobuf to code.
In my proto file, I designed a nested message as below:
message Object {
// something
};
message Response {
repeated Object list = 1;
};
In my C++ project, I try to insert an element:
Object obj;
Response res;
// res.mutable_list()->Add(obj); // ERROR!
res.mutable_list()->Add()->CopyFrom(obj);
I really don't why but Add(obj) will cause a compile error:
cannot bind 'Object' lvalue to 'Object&&'
res.mutable_info()->Add(obj);
I really couldn't understand why because in the header file, I did find the definitions of the funcitons inline void RepeatedPtrField<Element>::Add(Element&& value) and inline void RepeatedPtrField<Element>::Add(const Element& value). But both res.mutable_list()->Add(std::move(obj)); and res.mutable_list()->Add(obj); will cause some compile errors. Another error is as below, which I totally can't understand what it is:
no matching function for call to 'google::protobuf::RepeatedPtrField::TypeHandler::New(Google::protobuf::Area*&, std::remove_reference<Object&>::type)' TypeHandler::New(arena_, std::move(value));
res.mutable_list()->Add()->CopyFrom(obj); works but why can't I simply call Add(obj)?
Add(Object &&object) function requires object argument to be rvalue reference. You can cast to rvalue reference with std::move.
Object obj;
Response res;
res.mutable_list()->Add(std::move(obj)); // This should work.
However after using std::move, you can not access to obj variable anymore, if you try to acces it you will be greeted with segmentation fault. This is why with protobuf, it is much better to create your child message objects from your parent object.
I have C++14 enabled in code (a Qt5 project) similar to the following:
auto func = [&](auto p, auto pp) {
if(!p)
return;
pp = p;
p->init();
this->member_function(pp->thing()); // replaces member_function(pp->thing());
};
MyClass *p1;
...
func(p1, m_p);
m_p->doSomething();
After receiving:
internal compiler error: Segmentation fault
Debugging I found m_pdid not change after the call to func, as I was expecting. Does generic lambda (auto) really works so? How do I go to change m_p in code like the above?
File a bug report in gcc's bugzilla. Whether your code is valid C++, or not, the compiler should not blow up with a segmentation fault.
Segmentation fault in the compiler is very bad, but have you tried using auto& pp? It looks like m_p is being passed by value, not reference.
I understand where the problem is, I'm just not sure why am I not getting any error output from gcc.
The lines in question which generate the issue are:
std::string type,rel,pred;
std::tie( type, rel, pred ) = tuple;
auto supertype = std::make_shared<Node>( Token( type ) ); // This
auto predicate = std::make_shared<Node>( Token( pred ) ); // and this
FYI, Node Ctor is:
Node ( Token & token )
If I do this, I get no error:
auto type_token = Token( type );
auto pred_token = Token( pred );
auto supertype = std::make_shared<Node>( type_token );
auto predicate = std::make_shared<Node>( pred_token );
My GCC is:
posix gcc version 4.7.3 (Debian 4.7.3-8)
The actual error is:
> Internal compiler error: Error reporting routines re-entered. Please
> submit a full bug report, with preprocessed source if appropriate. See
> <file:///usr/share/doc/gcc-4.7/README.Bugs> for instructions.
Funnily enough, this directory above doesn't even exist.
What's wrong with constructing an object within the make_shared constructor?
A temporary object cannot bind to a non-const lvalue reference. You therefore cannot pass one to the specified Node constructor. The compiler should reject:
Node node1(Token(type));
Node node2(Token(pred));
The same is true for trying to get std::make_shared to perform the same initialization internally with your code:
auto supertype = std::make_shared<Node>( Token( type ) );
auto predicate = std::make_shared<Node>( Token( pred ) );
You are trying to get make_shared to pass that temporary object to the non-const lvalue constructor. The compiler should diagnose the program as ill-formed and fail to compile it. That is notably NOT the same thing as crashing with an ICE, which always indicates a compiler bug.
Workaround is to either do as you suggest in your "but this does work" code - pass an lvalue reference to make_shared - or to write an rvalue reference constructor for Node:
Node(Token&&);
EDIT: I think this is GCC bug# 56869 which appears to have been fixed in 4.6.4 and 4.7.4 and was closed on 2013-11-18. If anyone reading this can easily run this testcase in 4.7.4:
#include <memory>
#include <string>
struct Token {
Token(std::string lex);
};
struct Node {
Node(Token& token);
};
int main() {
auto supertype = std::make_shared<Node>(Token{"foo"});
auto predicate = std::make_shared<Node>(Token{"bar"});
}
please post the results in a comment.
I have a c++ program that compiles fine under gcc (4.8.1), icpc (13.1.3), clang++ (3.3) and runs okay except for the clang++ version which crashes with segfault. When I try to run this in the gdb or lldb debugger, I get EXC_BAD_ACCESS with address 0x0. The crash occurs in a member function of a helper class and the debugger claims that this has value 0x0. However going up one level, the pointer pimpl of the helper class is reported to have a non-null value and I can access its data, which look perfectly sensible.
here is some pseudo code (... is not the ellipse, but means "some parameters")
struct helper;
struct foo {
helper* pimpl;
foo(...);
void bar(...);
};
struct helper {
helper(...);
void hbar(...)
{
// crash here with *this = 0x0 according to debugger
}
};
foo::foo(...) : pimpl(new helper(...)) {}
void foo::bar(...)
{
pimpl->hbar(...); // pimpl NOT 0x0 according to debugger ??!
}
What could have gone wrong and how can I find out? Note: the question is NOT: "what is wrong with my code?"
edit 1 Perhaps it is worth mentioning that some of the arguments passed to helper::hbar() have been "optimised away by the compiler", according to the debugger, at the point of foo::bar()), while they have address 0x0 within helper::hbar()
edit 2 If I print out the value of this from within helper::hbar() the error does not occur.
edit 3 The error occurs with -O0 as well as -O2.
edit 4 The first arg of helper::hbar() was taken via const reference. If I change that to by value, everything works fine .... That argument was a spatial vector, similar to std::array<double,3>.
One way to do it - create a log file, print value of pimpl/some variable belonging to pimpl before
pimpl->hbar(...);,
and inside
pimpl->hbar(...);
Compare output from different compilers, try narrow down the problem that way adding more output to log file as you start seeing divergence...
I have 220 "unreachable code" warnings in Boost.Variant, class boost::detail::variant::invoke_visitor:
template <typename T>
result_type internal_visit(T& operand, int)
{
return visitor_(operand);
}
.
boost_1_50_0\boost\variant\variant.hpp(859): warning C4702: unreachable code
line return visitor_(operand);.
First of all, how is this possible at all to have unreachable code in this simple single-line function? Which code is unreachable?
I cannot reproduce this warning in a simple case, seems because I don't understand what exactly causes it. The warning appeared after I implemented operator== for classes used in boost::variant.
Environment: VC++ 2010, Boost 1.50
EDIT:
the warning happens only in Release build (optimized), and only if I compare boost::variants. I use boost::variant with primitive and custom types. Custom types implements typical bool operator(CT const& lh, CT const& rh) as free functions.
I had this problem myself in VS 2017. If the compiler determines visitor_(T&) will always throw an exception, the "unreachable" part is the return. If you were to unwrap that into the following:
auto v = visitor_(operand);
return v;
The compiler would call out return v; as unreachable. In my case, I was using a Policy-based class and a NullPolicy threw exceptions. I ended up just removing the exception.
Fun fact: if you have LTCG on, you only get the error during the linking stage, so you don't even know where to start. Turning off LTCG but leaving on optimizations will at least let you narrow it down by making compilation of offending files fail.
Just in case someone else stumbles over the same thing: (I experienced this with MSVS 2017 v15.7.4)
class Widget
{
public:
void bar()
{
foo = 0; // C4702 here
}
void foobar()
{
return; // NOTE direct return here
bar();
}
private:
int foo;
};
This was in old code where someone had "commented out" the entire function foobar() leaving the original code for "future reference". (yes, source control is very hard to use)
Now in release mode the compiler inlined the function bar() which resulted in a C4702: unreachable code warning, but it indicated the first line of function bar() where seemingly nothing was wrong. (actually each line of code after the return; triggered the warning)