Suppressing one warning from -Weffc++ [duplicate] - c++

This question already has answers here:
How to disable GCC warnings for a few lines of code
(9 answers)
How to suppress GCC warnings from library headers?
(10 answers)
Closed 9 years ago.
Adding the -Weffc++ flag already caught 2 real bugs in my code, so I'd like to leave it in. Unfortunately it leads to the following:
record-set.h:60:7: warning: ‘class RecordSet’ has pointer data members [-Weffc++]
record-set.h:60:7: warning: but does not override ‘RecordSet(const RecordSet&)’ [-Weffc++]
record-set.h:60:7: warning: or ‘operator=(const RecordSet&)’ [-Weffc++]
The warning is accurate. A RecordSet is basically a subset of a std::vector< Record > matching a rule. (I actually point to a data structure containing that, and a definition of what fields a Record has.) It has pointer data members because when I update a record, I need to update the original.
https://github.com/c42f/tinyformat/pull/4 offers the idea of just declaring the necessary functions to be private, then not use them. Unfortunately I do things like return a RecordSet from a function, so I need the copy constructor to actually exist with the default behavior.
The ideal would be to find some sort of inline comment that would tell gcc that yes, really, I want an exception here but please warn me about anything else that goes wrong.
Next best would be to write my own versions of those two functions that does exactly what the default does. I'm unfortunately not confident in my ability to get those exactly right. Can someone point me to a canonical example?
Easiest, of course, is to turn this flag off. But given that it caught real bugs for me, I would like to avoid that.

Related

What does mean "int(i)=1;"? [duplicate]

This question already has answers here:
Why does C++ allow us to surround the variable name in parentheses when declaring a variable?
(2 answers)
Closed 5 years ago.
I am new to C++, I see following syntax in c++ to initialize variable.
int(i)=1;
Then, I have compiled in G++ compiler and compiler did not give any error or warning.
So, What does mean int(i)=1; in C and C++?
Also, I have tested in C, I thought, the C compiler give an error but it's also working fine.
It's basically a strange way to write
int i = 1;
Nothing to worry about.
Sometimes, parenthesis around the variable name are necessary in defintions (eg. pointer to functions), and there is no reason to prohibit them for other cases, so it's allowed without any deeper reason.
Maythe the author didn't like spaces (such people exist).

Why is void used in this manner with an inline function? [duplicate]

This question already has answers here:
Why cast unused return values to void?
(10 answers)
Closed 6 years ago.
I just ran across this in some sample code and I've never seen it used before. For an inline function which returns a type but the return value is not used, the author preceded the call with a (void). Does this actually do anything?
Example:
inline some_object& SomeClass::doSomething();
SomeClass o;
(void)o.doSomething();
This is typically done when using a tool like Lint which has been configured to issue a warning if you call a function and ignore its return value.
This is (IMO) a horrible practice that's fostered by some tools1 that give warnings about calling a function and ignoring what it returns.
The right way to deal with the problem is to give the tool a list of functions whose return values can reasonably be ignored. If the tool doesn't support that, it's probably useless and should be thrown away. In the case of a compiler, you may not be able to throw away the tool itself, and may have to settle for just globally disabling that warning.
1. Most often something like lint, but some compilers can do the same.

What is the purpose of commenting out function argument names? [duplicate]

This question already has answers here:
Why comment parameter names rather than leave it as it is
(6 answers)
Closed 8 years ago.
I'm working with this sdk that generates a skeleton plugin project, as in, all the functions required by the host application are there, just not filled.
Initially, all the function definitions are sorta like this:
void Mod1::ModifyObject(TimeValue /*t*/, ModContext& /*mc*/, ObjectState* /*os*/, INode* /*node*/) {}
With the argument names commented out, why is that? As far as I can tell, if I'm not using the arguments, it makes no difference whether the names are there or not.
I guess there are two reasons for this:
It's deliberate to essentially only implement what's necessary: Function names and their signatures. They don't define any names, so it's up to you to either pick the suggestions or your own (or none at all).
It's to avoid extra-pedantic compilers complaining about unused variables that are defined as parameters. If you don't need a parameter, it's most efficient to simply drop it (unless you need it in some other implementation, but the compiler won't necessarily know about that). But then again they could also complain about params that are there, but not named (although you could consider that intentionally omitted).
Some compilers will issue a warning about unused named parameters, but not about unused unnamed parameters. GCC is one such compiler, if the -Wunused-parameter option is used, enabled by -Wextra.
The theory behind this is that an unused named parameter is more likely to be a mistake than an unused unnamed parameter. Of course, that theory doesn't apply to all code.
When you turn on treat warnings as errors, and you don't use a parameter, you'll need to comment out its name or delete it entirely.
There are sometimes macros such as Q_UNUSED in Qt, or you can just reference it in code without doing anything to make the compiler shut up.
void foo(int unused) {
(void) unused; // So the compiler doesn't emit a warning.
}

What is the use of a statement with no effect in C++? [duplicate]

This question already has answers here:
What is the purpose of the statement "(void)c;"?
(3 answers)
Closed 8 years ago.
In one library that I am using I saw this code:
template<typename T>
void f(SomeTemplatedClass<T> input)
{
(void)input;
...
use(input); // code that uses input
}
I have no idea what is the meaning of this code. If I remove the cast to void, I get a
statement has no effect
warning in gcc. So I suppose someone did it purposefully and purposefully added the cast to get a rid of the warning.
Do you have any experience with a statement that has no effect, yet it is needed for some reason?
EDIT:
Is it safe to assume that this has nothing to do with templates? For example circumventing an old compiler bug or the like?
This construct is a common way of tricking the compiler into not emitting a warning for unused parameters. I have not seen it used for any other purpose.
(void)input;
While it is common, it is also a really bad idea.
it is highly platform dependent -- it may work on one compiler and not another.
it is unnecessary. There is always a better way to deal with unused parameters. The modern way is to simply omit the parameter name.
it can get left behind if the code changes and the parameter is now used (as appears to be the case here).
it can backfire. Some compilers may treat this as invalid.
According to the C++ standard N3936 S5.4/11:
In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value expression. The expression is evaluated and its value is discarded.
A compiler would be entitled to observe that there is no side-effect and therefore this construct deserves at least a warning. According to #chris, MSVC is one of those compilers.

How to prevent warning C4355: 'this' : used in base member initializer list [duplicate]

This question already has answers here:
Initialize a reference - warning C4355: 'this' : used in base member initializer list
(5 answers)
Closed 9 years ago.
my question is similar into this one, but I hadn't found info that I need. I have my class constructor.
CustomTreeViewItem::CustomTreeViewItem(CustomTreeView* list)
: m_childs(), m_expanded(false), m_list(list), m_components(), m_depth(1),
m_rect(), m_root(this)
{}
I use this pointer in constructor but do not call any methods from that so I do not invoke undefined behavior. So everything is fine, but I got warning, now I'm writing some lib (little framework) so I have to write error-free code. So I have changed my code into this:
CustomTreeViewItem::CustomTreeViewItem(CustomTreeView* list)
: m_childs(), m_expanded(false), m_list(list), m_components(), m_depth(1),
m_rect(), m_root(NULL)
{
m_root = this;
}
Now I do not get any warning, however in this way I lose performance (very slightly, but anyway it is loss). I want to ask if there isn't any way to keep the highest performance and prevent this warning.
If the pointer is only stored for later use, the Standard guarantees this is perfectly safe.
You likely will need to use a pragma to disable the warning. And warning control is non-portable (other compilers will likely just ignore your pragma and continue to warn).
First thing is that the compiler should not complain about that, the next thing is that the alternative version of the code, where the m_root is set to NULL (should be nullptr) and later to this will most probably not have a performance impact at all. Any optimizing compiler should be able to merge both writes into a single write with this. Take a look at the assembly. Even if that triggered an extra write, the variable is hot, so it is just an L1 write and the cost would not be noticeable.