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.
Related
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&.
On a recent bug hunt, I found an issue with returning a pointer to a member of a temporary variable. The offending (simplified) code was:
struct S {
S(int i) : i(i) {}
int i;
int* ptr() { return &i; }
};
int* fun(int i) { return S(i).ptr(); } // temporary S dies but pointer lives on
int main() {
int* p = fun(1);
return *p; // undefined
}
How to prevent this? GCC & Clang have -Waddress-of-temporary and -Wreturn-stack-address but they seem to loose trail because of ptr() acting as a middle man for the dirty deeds. They are only triggered when the pointer is taken directly:
int* fun(int i) { return &S(i).i; } // rightly fails to compile
My project also incorporates cppcheck in continuous integration but it also can't pick it up (raised here).
Which static analysis tool can prevent this class of bugs?
EDIT: GCC does pick it up since version 6.1.0 with -Wreturn-local-addr and (surprisingly) -O2 switched on.
I am a Cppcheck developer.
My project also incorporates cppcheck in continuous integration but it also can't pick it up.
interesting bug. This is the kind of bug that cppcheck wants to warn about. We have some related checks but this slipped through unfortunately.
Not really surprising given the regex nature of cppcheck.
I don't personally understand why some people say cppcheck is a regex tool.
It uses AST, context sensitive valueflow analysis, etc to detect bugs. So does GCC and Clang. Cppcheck is sometimes claimed to be a regex tool but GCC and Clang are not.
I have made a program that contains the following function in C:
void *e_malloc(size_t size)
{
void *m = malloc(size);
if (!m)
{
printf("Out of memory, fatal error.");
abort();
}
return m;
}
I am using this as an error free malloc that exits the program when out of memory. The thing is, that when I compile the code in linux with g++, I get an error because it says that it needs to be casted, and as you can see I always return a void pointer cause that's what malloc returns (gcc of course compiles fine). Is there a way I could modify this function to make it work on both compilers ? Do I just have to cast it every time ? Are there other options to make what I am trying to do ?
Also, when I use Cmake (through Clion IDE) the code compiles just fine with "-std=C++11". Why is that ?
You could make it easier to use with macros:
#define e_new(type) ((type*)malloc(sizeof(type)))
#define e_new_array(type, count) ((type*)malloc((count)*sizeof(type)))
example usage:
graph_t *g = e_new(graph_t);
graph_t *ten_gs = e_new_array(graph_t, 10);
Note that this is not specific to your e_malloc - malloc itself has the same problem in C++.
As the compiler error clearly states, the error is in your calling code, not in your e_malloc.
You probably have something like this:
graph_t *g;
g = e_malloc(sizeof(graph_t));
The error is the type conversion between the void * returned by e_malloc and the expected graph_t*. Regular malloc shows the same behavior. You need to do the typecast explicitly:
g = (graph_t*)e_malloc(sizeof(graph_t));
You should not be using this construct in C++ at all. In C++, you need to use new, not malloc - and new already throws an exception (by default). Problem solved.
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)