Cppcheck inline suppression not working - cppcheck

Example code:
class Foo {
// cppcheck-suppress noExplicitConstructor
Foo(int foo) { }
}
Cppcheck call:
$ cppcheck.exe --enable=all foo.cpp
Checking foo.cpp...
[foo.cpp:3]: (style) Class 'Foo' has a constructor with 1 argument that is not explicit.
How can I suppress this error?

This way:
class Foo {
// cppcheck-suppress noExplicitConstructor
Foo(int foo) { }
};
It requires --inline-suppr as command line argument.

Related

Error: no matching function for call to ‘foo::foo()’

I have the following two files
foobar.h
#ifndef FOOBAR_H
#define FOOBAR_H
#include <cstring>
class Foo {
public:
int x;
Foo(int x);
};
class Bar {
public:
char* name;
Foo foo;
Bar(Foo foo);
};
#endif // FOOBAR_H
and foobar.cpp
#include "foobar.h"
Foo::Foo(int x) {
// Do something
}
Bar::Bar(Foo foo) {
// Do something
}
Attempting to compile these with g++ -c foobar.cpp -o foobar.o results in the following error:
foobar.cpp: In constructor ‘Bar::Bar(Foo)’:
foobar.cpp:9:17: error: no matching function for call to ‘Foo::Foo()’
Bar::Bar(Foo foo) {
^
foobar.cpp:5:1: note: candidate: ‘Foo::Foo(int)’
Foo::Foo(int x) {
^~~
foobar.cpp:5:1: note: candidate expects 1 argument, 0 provided
In file included from foobar.cpp:1:
foobar.h:5:7: note: candidate: ‘constexpr Foo::Foo(const Foo&)’
class Foo {
^~~
foobar.h:5:7: note: candidate expects 1 argument, 0 provided
foobar.h:5:7: note: candidate: ‘constexpr Foo::Foo(Foo&&)’
foobar.h:5:7: note: candidate expects 1 argument, 0 provided
As far as I understand the output of g++ is that it requires me to have a default constructor for foo. Why? I wish to pass a foo object to the constructor of bar, why would it need to invoke a default constructor anywhere? I do not want to have a no-args constructor anyways, since I NEED that x has a specific user defined value.
You are trying to default construct a Foo here:
Bar::Bar(Foo foo) {
// the member variable `foo` would have been default constructed here
// Do something
}
But Foo doesn't have a default constructor. One possible solution would be to initialize it in the member initializer list:
Bar::Bar(Foo foo) : foo(std::move(foo)) { // now uses the move constructor instead
// Do something
}

Two-stage templated alias not resolvable in constructor?

I am trying to work with a two-stage templated alias, but I cannot get the alias to be accepted as a constructor parameter. Is there a way to do this?
An example of what I am trying to do is seen in the following code:
#include <memory>
template <typename Bar>
class Foo
{
public:
using FooPtr = std::shared_ptr<Foo<Bar> >;
static FooPtr getFooPtr(Bar someBar) { return std::make_shared<Foo<Bar> >(someBar); }
Foo(Bar bar) : _bar(bar) {}
Bar getBar() { return _bar; }
private:
Bar _bar;
};
template <typename Bar>
class Foobar
{
public:
using FB = Foo<Bar>;
Foobar(FB::FooPtr fooPtr)
: _fooPtr(fooPtr)
{
}
FB::FooPtr getFooPtr() { return _fooPtr; }
private:
FB::FooPtr _fooPtr;
};
int main()
{
Foobar myFoobar<int>(f::getFooPtr(4));
return myFoobar.getFooPtr()->getBar();
}
When I compile this with g++, I get the following:
dev#ubuntu:~/test/fsm$ g++ -std=c++1z test.cpp
test.cpp:23:23: error: expected ‘)’ before ‘fooPtr’
Foobar(FB::FooPtr fooPtr)
^
test.cpp:28:5: error: need ‘typename’ before ‘Foobar<Bar>::FB::FooPtr’ because ‘Foobar<Bar>::FB’ is a dependent scope
FB::FooPtr getFooPtr() { return _fooPtr; }
^
test.cpp:31:5: error: need ‘typename’ before ‘Foobar<Bar>::FB::FooPtr’ because ‘Foobar<Bar>::FB’ is a dependent scope
FB::FooPtr _fooPtr;
^
test.cpp: In function ‘int main()’:
test.cpp:36:11: error: missing template arguments before ‘myFoobar’
Foobar myFoobar<int>(f::getFooPtr(4));
^
test.cpp:37:11: error: ‘myFoobar’ was not declared in this scope
return myFoobar.getFooPtr()->getBar();
Is the compiler not recognizing the alias FB in the Foobar constuctor? Or is it a problem with resolving Foo::FooPtr to a type?
Thanks!

boost move compile error

I'm trying to implement the move constructor outside the class body, but it won't compile correctly
#include <boost/move/move.hpp>
class Test
{
BOOST_COPYABLE_AND_MOVABLE(Test)
public:
Test() {}
Test(const Test & other) { }
Test(BOOST_RV_REF(Test) other);
Test & operator=(BOOST_COPY_ASSIGN_REF(Test) other) { return *this; }
Test & operator=(BOOST_RV_REF(Test) other) { return *this; }
};
Test::Test(BOOST_RV_REF(Test) other) { }
I compiled this code with g++, my g++ version is 4.4.7
$ g++ -c test.cpp
test.cpp:15: error: prototype for 'Test::Test(boost::rv<Test>&)' does not match any in class 'Test'
test.cpp:9: error: candidates are: Test::Test(boost:rv<Test>&)
test.cpp:8: error: Test::Test(const Test&)
test.cpp:7: error: Test::Test()
It also failed with g++ 5.4.0 – flyzero
Must be your boost version.
It works fine with g++ 5.4.1 and Boost 1.64. If not, check the preprocessor output for any include/macro mishaps.
In Linux, ::boost::rv is declared with may_alias attribute. My code compile correctly after removing the may_alias attribute.
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
template <class T>
class rv
: public ::boost::move_detail::if_c
< ::boost::move_detail::is_class<T>::value
, T
, ::boost::move_detail::nat
>::type
{
rv();
~rv() throw();
rv(rv const&);
void operator=(rv const&);
} BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;

Error: 'xxx' is not a type [duplicate]

This question already has an answer here:
Why can in-class initializers only use = or {}? [duplicate]
(1 answer)
Closed 6 years ago.
In this complete code:
class foo
{
public:
foo(const int pin);
};
class bar {
public:
// Constructor
bar(const int dataPin) : dataPin_ (dataPin) { }
private:
const int dataPin_;
foo myFoo_ (dataPin_); // instance of foo
};
int main (void)
{
return 0;
}
Using g++ 4.8.4 I get the error:
g++ -Wall -c "test.cpp" (in directory: /home/nick/Development)
test.cpp:14:17: error: ‘dataPin_’ is not a type
foo myFoo_ (dataPin_); // instance of foo
^
Compilation failed.
Using clang 3.4-1ubuntu3 I get:
test.cpp:14:17: error: unknown type name 'dataPin_'
foo myFoo_ (dataPin_); // instance of foo
^
1 error generated.
Why does it want a type here? This is attempting to create an instance of foo as a class variable of bar. The variable dataPin_ is declared directly above.
If I change the line with the error to this, it compiles cleanly:
foo myFoo_ (int dataPin_); // instance of foo
It's reading foo myFoo_ (dataPin_); as a function declaration: myFoo_ is a function taking a dataPin_ and returning a foo. That's why it's expecting a type name in ( ).
To fix this, initialize myFoo_ in your constructor, just like you did with dataPin_:
bar(const int dataPin) : dataPin_ (dataPin), myFoo_(dataPin) {}
Here you should add type not variable, this is the function signature, it should has types not variables.
foo myFoo_ (dataPin_); // instance of foo

Compiler complains about BOOST_CHECK_THROW on constructor

The following does not compile:
class Foo {
public:
Foo( boost::shared_ptr< Bar > arg );
};
// in test-case
boost::shared_ptr< Bar > bar;
BOOST_CHECK_THROW( Foo( bar ), std::logic_error ); // compiler error here
The implementation of Bar does not matter. The compiler complains, that Foo does not have an appropriate default constructor (VC++ 2005). If I add a default constructor, it works, and it actually gets called. Why does this statement require a default constructor?
This occurs because BOOST_CHECK_THROW is a macro, and Foo(bar) is being expanded to a statement. The compiler sees this statement and interprets it as a variable declaration Foo bar; which requires a default constructor.
The solution is to give the variable a name:
BOOST_CHECK_THROW( Foo temp( bar ), std::logic_error );
In other words BOOST_CHECK_THROW will expand to something like
try
{
Foo(bar);
// ... fail test ...
}
catch( std::logic_error )
{
// ... pass test ...
}
and the compiler is interpreting Foo(bar); as the declaration of a variable called bar. One can check this with a simple program:
struct Test
{
Test(int *x) {}
};
int main()
{
int *x=0;
Test(x);
return 0;
}
which gives the following errors with g++
test.cpp: In function ‘int main()’:
test.cpp:10: error: conflicting declaration ‘Test x’
test.cpp:9: error: ‘x’ has a previous declaration as ‘int* x’