Warnings for uninitialized members disappear on the C++11 - c++

I compile this simple program:
#include <cstdio>
#include <iostream>
using namespace std;
struct Foo
{
int a;
int b;
};
struct Bar
{
//Bar() = default;
int d;
};
int main()
{
Foo foo;
Bar bar;
printf("%d %d\n", foo.a, foo.b);
return 0;
}
and I get those warnings:
$ g++ -std=c++11 -Wall -Wextra -Wpedantic foo.cpp -o foo
foo.cpp: In function ‘int main()’:
foo.cpp:21:9: warning: unused variable ‘bar’ [-Wunused-variable]
Bar bar;
^
foo.cpp:23:11: warning: ‘foo.Foo::b’ is used uninitialized in this function [-Wuninitialized]
printf("%d %d\n", foo.a, foo.b);
^
foo.cpp:23:11: warning: ‘foo.Foo::a’ is used uninitialized in this function [-Wuninitialized]
Of course, this is what we expect. But when I uncomment the Bar default ctor, there is a problem - all warnings disappear.
Why the Bar ctor disables warnings for Foo?
My GCC version is: g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609.
The problem does not occur on the C++03, only on the C++11 or newer.

It's a compiler bug, which as Jarod pointed out, has been fixed.

Related

Why is GCC warning me about a useless cast when using an inherited constructor?

Consider the following C++ code:
#include <string>
struct A {
A(const std::string& s): s(s) {}
std::string s;
};
struct B: A {
using A::A;
};
int main() {
B b("test");
}
When I compile it via GCC 6.2.1 with the -Wuseless-cast parameter
g++ -std=c++14 -Wuseless-cast test.cpp -o test
it emits the following warning:
test.cpp: In constructor ‘B::B(const string&)’:
test.cpp:9:14: warning: useless cast to type ‘const string& {aka const std::__cxx11::basic_string<char>&}’ [-Wuseless-cast]
using A::A;
^
test.cpp: In function ‘int main()’:
test.cpp:13:15: note: synthesized method ‘B::B(const string&)’ first required here
B b("test");
^
However, when I change the definition of B to
struct B: A {
B(const std::string& s): A(s) {}
};
the warning goes away.
Questions:
Why is the warning emitted?
Why does specifying a constructor for B instead of inheriting it from A fixes the warning?
Your example can be further reduced to:
struct A {
A(const int& i): i(i) {}
int i;
};
struct B: A {
using A::A;
};
int main() {
B b(0);
}
That is an open issue on GCC.
Including <string> isn't apparently required to reproduce it.
Note that the issue is still unconfirmed and it is known to affect at least GCC 6.1 - by looking at your question I would say that it affects also GCC 6.2.
You are probably facing a known GCC bug (PR 70844).

c++11 and gcc: internal compiler error: in convert_move

I have the following code:
typedef int __v8si __attribute__ ((__vector_size__ (32)));
class T
{
public:
__v8si v;
__attribute__((target("avx2")))
T(int p ):v(__extension__ __v8si{p,p,p,p,p,p,p,p}){}
__attribute__((target("avx2")))
T(__v8si p):v(p){}
__attribute__((target("avx2")))
T operator * ( T b ) const
{
return __builtin_ia32_pmulld256( v , b.v ) ;
}
};
void h(int *);
__attribute__((target("default")))
void h(int *)
{
}
__attribute__((target("avx2")))
void h(int *)
{
const T a(1);
const T b(2);
const T c (a * b);
}
int main()
{
return 0;
}
If I try to compile it,
I have the following error:
$ gcc test.cpp -std=c++11
test.cpp: In member function 'T T::operator*(T) const':
test.cpp:17:48: internal compiler error: in convert_move, at expr.c:315
return __builtin_ia32_pmulld256( v , b.v ) ;
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
I have tried to compile it with various gcc versions:
4.9.2, 5.3 and several other versions.
Have you any ideas why it happens, and how could I solve the problem?
gcc test.cpp -std=c++11 -mavx2 works.
gcc test.cpp -std=c++11 -O1 works.
but I want to compile the code with -O0
Update 1. I've filed a bug report. The report is available here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77952

running clang scan-build with g++ on linux

I have the following code:
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
void foo() const;
};
void A::foo() const {}
std::unique_ptr<A> foo2()
{
std::unique_ptr<A> pa(new A());
return pa;
}
void
foo()
{
const A& ra = *foo2();
ra.foo();
}
int
main()
{
foo();
return 0;
}
I am trying to use clang's scan-build:
scan-build g++ --std=c++11 unique_ptr.cpp
This program compiles and runs fine with g++.
I am using CentOS and clang3.8 and g++4.8.5.
Error Message:
error: no type named 'unique_ptr' in namespace 'std'
std::unique_ptr<A> foo2()
~~~~~^
You should use:
scan-build g++ -std=c++11 unique_ptr.cpp
Instead of:
scan-build g++ --std=c++11 unique_ptr.cpp
-std works (while --std doesn't) because scan-build checks specifically for the -std flag.
In clang/tools/scan-build/libexec/ccc-analyzer:
if ($Arg =~ /^-std=/) {
push #CompileOpts,$Arg;
next;
}

using std::map gives warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules

I've reduced a case to the code shown below here.
When compiling, this gives the following:
$ g++ -std=c++0x -O2 -Wall t.cpp
t.cpp: In function ‘int main()’:
t.cpp:20: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules
t.cpp:19: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules
/usr/lib/gcc/i686-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:175: note: initialized from here
What is this warning telling me ? What can I do about it ?
#include <stdio.h>
#include <stdint.h>
struct TimeKey {
uint64_t time_stamp;
uint64_t msg_no;
TimeKey(uint64_t tstamp, uint64_t no) :
time_stamp(tstamp),
msg_no(no)
{}
bool operator < (const TimeKey &other) const
{
if (time_stamp == other.time_stamp) //line 19
return msg_no < other.msg_no; //line 20
else
return time_stamp < other.time_stamp;
}
};
template <typename T>
class TimeBuffer {
public:
uint64_t counter;
std::map<TimeKey, T> messages;
void AddMsg(uint64_t tstamp, T val) {
messages[TimeKey(tstamp, counter++)] = val;
}
};
int main(void)
{
TimeBuffer<int> messages;
messages.AddMsg(123456, 1);
}
Note, this is on RHEL 6.3, which comes with gcc 4.4.6
This is a known (and fixed) compiler bug, see this and this. You should update your toolchain.

Does clang++ support __restrict?

The following code compiles with g++ 4.7.1 but not clang 3.1
struct A
{
int foo();
};
int A::foo() __restrict
{
return 0;
}
int main(int argc, char * argv[])
{
A a;
return a.foo();
}
Does clang support __restrict? or is it using a particular syntax?
I don't have clang 3.1 handy, but under clang 4.1, I get this error:
t.cpp:6:8: error: out-of-line definition of 'foo' does not match any declaration
in 'A'
int A::foo() __restrict
^~~
t.cpp:3:7: note: member declaration nearly matches
int foo();
^
1 error generated.
clang 4.1 compiles it successfully if I change the declaration of A::foo to this:
int foo() __restrict;