I have an unfortunate problem. My GCC 4.6.3 compiler refuses to compile my move constructor.
Exchanging line 6 in the example with "MemoryBlock(const MemoryBlock & other)" would make it compile, but not using the below move constructor declaration. Seems like the compiler does not know C+11, even though it should using 4.6.3. Right?
#include <cstddef>
class MemoryBlock
{
public:
MemoryBlock(MemoryBlock && other) //<----------- RAD 6.
{
}
private:
size_t _length; // The length of the resource.
int* _data; // The resource.
};
int main() {
}
Compiler output:
prog.cpp:6:28: error: expected ‘,’ or ‘...’ before ‘&&’ token
prog.cpp:6:36: error: invalid constructor; you probably meant ‘MemoryBlock (const MemoryBlock&)’
make: * [slask] Error 1
GCC version:
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 (Kör från labbsal i skolan)
makefile:
%.out: %.cpp
g++ -g -W -Wall -std=c++0x $*.cpp -o $*.out;
Try -std=c++11 instead of -std=c++0x. While your compiler knows the usage, the -std=c++0x "turns off" those new rules.
Related
Given the following source code:
#include <memory>
#include <typeinfo>
struct Base {
virtual ~Base();
};
struct Derived : Base { };
int main() {
std::unique_ptr<Base> ptr_foo = std::make_unique<Derived>();
typeid(*ptr_foo).name();
return 0;
}
and compiled it with:
clang++ -std=c++14 -Wall -Wextra -Werror -Wpedantic -g -o test test.cpp
Enviroment setup:
linux x86_64
clang version 5.0.0
It does not compile because of warning (note -Werror):
error: expression with side effects will be evaluated
despite being used as an operand to 'typeid'
[-Werror,-Wpotentially-evaluated-expression]
typeid(*ptr_foo).name();
(Just a note: GCC does not claim that kind of potential problematic)
Question
Is there a way to get the information about the type pointed by a unique_ptr without generating that kind of warning?
Note: I am not talking about disabling -Wpotentially-evaluated-expression or avoiding -Werror.
Looks like following should work without warnings and give correct result for derived class
std::unique_ptr<Foo> ptr_foo = std::make_unique<Bar>();
if(ptr_foo.get()){
auto& r = *ptr_foo.get();
std::cout << typeid(r).name() << '\n';
}
I am currently going through Bjarne Stroustrup's "The C++ Programming Language (4th Edition)" and am trying to understand whether is the following a syntax error or was it the way I compiled it.
According to the following code snippet (extracted from the book), my constructor should look like this:
class Vector {
public:
Vector(int s): elem{new double[s]}, sz{s} {} // Construct a Vector
...
private:
double* elem; // Pointer to the elements
int sz; // The number of elements
};
But, I am unable to compile it unless I change the following as per the suggestion of the error message:
Vector(int s): elem(new double[s]), sz(s) {}
Note: I compiled my C++ codes using the following command through the Mac Terminal:
g++ -ansi -pedantic -Wall Test.cpp -o Test.o
Thank you in advance.
Probably, all you need to do is to compile it for C++ 11:
g++ -std=c++11 -ansi -pedantic -Wall Test.cpp -o Test.o
As #molbdnilo pointed out in a comment, remove -ansi from the command, because this is a synonym for std=c89 or std=c++98.
g++ -std=c++11 -pedantic -Wall Test.cpp -o Test.o
Test environment:
CentOS 7.0 g++ 4.8.2
Arch Linux g++ 4.9.0 20140604 (prerelease)
Arch Linux g++ 4.9.1
Compile command cases:
PASS: g++ -Wall t.cpp
FAIL: g++ -Wall -O2 t.cpp
PASS: g++ -Wall -O2 t.cpp # and replace 2 with 3 on line 13
PASS: g++ -Wall -O2 t.cpp # and comment out line 14
PASS: g++ -Wall -O2 --std=c++11 t.cpp # for g++ 4.8/4.9
The FAIL message:
t.cpp: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vecto
<_Tp, _Alloc>::iterator, const _Tp&) [with _Tp = Object; _Alloc = std::allocator<Ob
ject>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<Object*, s
td::vector<Object> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = Object*]’
t.cpp:17:15: warning: array subscript is above array bounds [-Warray-bounds]
~Object() {};
^
t.cpp:17:15: warning: array subscript is above array bounds [-Warray-bounds]
t.cpp
#include <vector>
class TestCls {
public:
TestCls() {};
virtual ~TestCls() {};
};
class TestCls1 : public TestCls
{
};
class Object {
public:
TestCls m_member[2];
TestCls1 m_member1[2]; // LINE 13, if change to [3] it works.
TestCls1 m_member2[2]; // LINE 14, if comment out this line, it works.
Object() {};
~Object() {}; // LINE 17 the warning line
};
class Container {
public:
std::vector<Object> m_obj;
Container() {};
~Container() {};
};
int main() {
Container con;
Object obj;
con.m_obj.push_back(obj);
}
This is a type of bogus warning generated by GCC due to issues with Value Range Propagation (which is the middle-end pass that generates array bounds warnings) interacting with the various loop optimizer passes (such as loop peeling and loop unrolling). As is mentioned in the various bugzillas linked, these represent missed optimization opportunities as well, but the underlying issue (or issues) in VRP have proved elusive for the GCC developers. That said, reporting this occurrence to the GCC Bugzilla is a good idea, especially since you have a MWE at hand.
I found a solution, but I don't know the reason.
// ...
class Object {
public:
// ...
~Object();
};
Object::~Object() {}; // move to outside LINE 19
//...
gcc -Wall enables all compiler's warning messages. This option should
always be used, in order to generate better code.
So, try delete -Wall. Example:
with -Wall http://goo.gl/d4cces
without -Wall http://goo.gl/4vY2Un
I'm lost as to why Clang rejects the following code:
#include <typeinfo>
#include <exception>
const char* get_name( const std::exception_ptr eptr )
{
return eptr.__cxa_exception_type()->name();
}
int main() {}
It OK with GCC, but Clang complains about type_info being an incomplete type:
$ g++-4.7 -std=c++0x -O3 -Wall -Wextra t.cc -o t
$ clang++-3.2 -std=c++0x -O3 -Wall -Wextra t.cc -o t
t.cc:6:37: error: member access into incomplete type 'const class type_info'
return eptr.__cxa_exception_type()->name();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/exception_ptr.h:144:19: note: forward declaration of
'std::__exception_ptr::type_info'
const class type_info*
^
1 error generated.
$
Question: How do I fix it with Clang? Or am I missing something and Clang is right to reject the code?
Thanks to #HowardHinnant's comment, I managed to fix the problem. The problem became obvious in the preprocessor output: libstdc++ includes <exception> from <type_info> before it even declared std::type_info. That made Clang assume a new forward-declaration std::__exception_ptr::type_info. The solution is as simple as it is illegal:
namespace std { class type_info; }
#include <typeinfo>
#include <exception>
const char* get_name( const std::exception_ptr eptr )
{
return eptr.__cxa_exception_type()->name();
}
int main() {}
Seems like I should check if libstdc++ already has a bug report for that and, if not, create one.
UPDATE: Bug #56468 is now fixed for GCC 4.7.3+
Have a look at this piece of C++ code:
class Foo
{
int a;
public: Foo(int b): a(a) {}
};
Obviously, the developer meant to initialize a with b rather than a itself, and this is a pretty hard to spot error.
Clang++ will warn about this possible mistake while GCC won't, even with additional warnings enabled:
$ clang++ -c init.cpp
init.cpp:5:27: warning: field is uninitialized when used here [-Wuninitialized]
public: Foo(int b): a(a) {}
^
$ g++ -Wall -Wuninitialized -Winit-self -c init.cpp
$
Is there any chance of enabling the same output for g++?
Use a newer gcc :-) Seems to work fine for me:
stieber#gatekeeper:~$ g++ -Wall -Wuninitialized -Winit-self -c Test.cpp
Test.cpp: In constructor ‘Foo::Foo(int)’:
Test.cpp:5:9: warning: ‘Foo::a’ is initialized with itself [-Wuninitialized]
stieber#gatekeeper:~$ gcc --version
gcc (Debian 4.7.1-2) 4.7.1