In the following code (which is a minimal example based on a much more complex code), a base class defines a struct local to the class. A derived class overrides this definition, but uses also the definition in the base class.
#include <iostream>
struct base {
struct update;
void apply(int& x);
};
struct base::update {
void operator()(int& x)
{
++x;
}
};
void base::apply(int& x) { update{}(x); }
struct deriv : public base {
struct update;
void apply(int& x, int& y);
};
struct deriv::update {
void operator()(int& x, int& y)
{
typename base::update{}.operator()(x);
++y;
}
};
void deriv::apply(int& x, int& y) { update{}(x, y); }
int main()
{
base b;
int x = 1;
b.apply(x);
std::cout << x << std::endl;
int y = 2;
deriv d;
d.apply(x, y);
std::cout << x << ' ' << y << std::endl;
return 0;
}
Compiling with gcc and -Wall -Wextra
does not issue any warning.
The output of the code is as expected
2
3 3
However, when analyzing the code with cppcheck, with --enable=all
, I get the following:
Checking test.cpp ...
test.cpp:25:24: style: Parameter 'x' can be declared with const [constParameter]
void operator()(int& x, int& y)
^
test.cpp:9:1: error: The one definition rule is violated, different classes/structs have the same name 'update' [ctuOneDefinitionRuleViolation]
struct base::update {
^
test.cpp:24:1: note: The one definition rule is violated, different classes/structs have the same name 'update'
struct deriv::update {
^
test.cpp:9:1: note: The one definition rule is violated, different classes/structs have the same name 'update'
struct base::update {
The first reported error (Parameter 'x' can be declared with const
) seems clearly a false positive, as clearly I need non-const reference to be able to modify it, and in fact the code obviously does not compile with a const int&
.
But what about the second error on ODR violation? Is this a correct diagnose, and if so why cannot I override the definition of update
?
It is also a false positive. There is nothing wrong with declaring a nested class of the same name in the derived class. The two nested classes will be separate entities and each can have one definition per one-definition-rule.