GCC turn on compiler warnings for (sint64)~(sint64)(myVariable) ) - casting

Is there any compiler flag that I can use to set a warning for the following?
myVariable2 = (sint64)~(sint64)(myVariable1) )

Related

My g++ generates weird warning with vector<weak_ptr> erase() method

I have following C++ code:
#include <memory>
#include <vector>
#include <string>
#include <unordered_map>
void erase_from_vector(std::vector<std::weak_ptr<int>> &mvec) {
for (auto mvec_it = mvec.begin(); mvec_it != mvec.end(); )
mvec_it = mvec.erase(mvec_it);
}
int main(void) {
#if 0
std::vector<std::weak_ptr<int>> mvec;
for (auto mvec_it = mvec.begin(); mvec_it != mvec.end(); )
mvec_it = mvec.erase(mvec_it);
#endif
}
GCC generates warning when I compile it this way:
ppk#fif-cloud-dev:~$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
ppk#fif-cloud-dev:~$ g++ -fstrict-overflow -Wstrict-overflow=5 -O2 -std=c++14 warn1.cc
warn1.cc: In function ‘void erase_from_vector(std::vector<std::weak_ptr<int> >&)’:
warn1.cc:6:6: warning: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Wstrict-overflow]
void erase_from_vector(std::vector<std::weak_ptr<int>> &mvec) {
^
But when I change -O2 flag to -O1 it compiles without any warnings. When I keep flag -O2 and uncomment code in main() it also compiles without any warnings. Clang compiler also does not report any warnings.
I suppose that this warning comes from std::weak_ptr destructor where counter is decremented but have no idea why it appears in my code.
Is the warning caused by my error or error in the compiler?
Most likely a quirk of gcc 5.4. It's gone as soon as you get to gcc 6.1, and I don't see it reappear again in any later version.
gcc 5.4 (warnings)
gcc 6.1 (no warnings)
It's especially damning that Clang doesn't reproduce the behavior.
It should be noted that such behavior isn't exactly a bug, according to the doc (emphasis mine)
An optimization that assumes that signed overflow does not occur is perfectly safe if the values of the variables involved are such that overflow never does, in fact, occur. Therefore this warning can easily give a false positive: a warning about code that is not actually a problem.
That you're using -Wstrict-overflow=5 makes it even more likely, as this is the highest warning level that comes with its own disclaimer:
this warning level gives a very large number of false positives
My suggestion is to either upgrade your compiler or accept that gcc 5.4 is going to give you a false positive here.

Which Clang warning is equivalent to Wzero-as-null-pointer-constant from GCC?

Our project uses C++11/14, and we want to use nullptr instead of 0 or NULL with pointers, even when 0 (as an integer literal) is allowed.
I have the following code:
int main()
{
int *ptr1 = nullptr; // #1
int *ptr2 = 0; // #2
}
If I compile with GCC (5.3.0) and the flag -Wzero-as-null-pointer-constant it warnings in #2, but I can't find a similar flag in Clang. If I compile the code with Clang (3.7.1) and the flag -Weverything, I don't get any warning about #2.
So, is there any way to get a similar warning for this in Clang?
clang has this warning as of 5.0; I added it here.
Clang doesn't support these kind of warnings (i.e., there's no -Wzero-as-null-pointer-constant equivalent in Clang). You can see it your self if you add -Weverything option (mind do it only for testing), which enables all Clang's warnings.
Live Demo

unused-variable warning different for auto variables

Using gcc (4.7.2 here) I get warnings about unused auto variables, but not about other variables:
// cvars.h
#ifndef CVARS_H_
#define CVARS_H_
const auto const_auto = "const_auto";
const char const_char_array[] = "const_char_array";
const char * const_char_star = "const_char_star";
const char use_me = 'u';
#endif // CVARS_H_
//---
//comp_unit.cpp
#include "cvars.h"
void somef()
{
//const_auto // commented out - unused
use_me; // not using any of the others either
}
// compile with $ g++ -std=c++11 -Wunused-variable -c comp_unit.cpp
// gcc outputs warning: ‘cvars::const_auto’ defined but not used [-Wunused-variable]
// but does not complain about the other variables
Is this an inconsistency in GCC?
1.1 If so, what should happen in all cases, warning or no warning?
1.2 If not, what is the reason for the difference in behavior?
Note: Concerning 1.1, I imagine no warning should be printed in this case (this is what clang does). Otherwise, any compilation unit including a constant-defining header but not using all the constants within would contain lots of warnings.
These warnings are entirely up to the implementation, so there is no "should". But, yes, I agree: constants would ideally not generate these warnings even when declared using auto.
Since I can reproduce your observation in GCC 4.7 and GCC 4.8.0, but not in GCC 4.8.1 or 4.9, I'd say the guys over at GNU would agree too. In fact, I believe you're seeing bug 57183.

Compilation warning not present (GCC and g++)

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(int argc, char* argv[])
5 {
6 int bret = 1;
7 bret - 2;
8
9 printf("bret=%d",bret);
10 return 0;
11 }
In line:7, there was no left hand operator to reveice the value, still compiler was not generating any warning, GCC and g++ both. Is there anyintended purpore behind this?
[ADDED/EDIT]
As per comment I shall get warning only after using following flags: -Wall -Wextra
[debd#test]$gcc -Wall -Wextra test2.c
test2.c: In function 'main':
test2.c:7: warning: statement with no effect
test2.c:4: warning: unused parameter 'argc'
test2.c:4: warning: unused parameter 'argv'
[debd#test]$
As far as the language is concerned, there's no error - a statement is not required to have a side effect.
However, since a statement that does nothing is almost certainly a mistake, most compilers will warn about it. Yours will, but only if you enable that warning via the command line arguments.
You can enable just that warning with -Wunused-value, but I suggest you enable a decent set of warnings (including this one) with -Wall -Wextra.
As you found, this will also give a warning that the function parameters are unused. Since this is main, you can easily fix it by changing the signature to not have any parameters:
int main()
More generally, to avoid the warning if you need to ignore parameters, C++ allows you not to name them:
int main(int, char**)
and both languages allow you to explicitly use but ignore the value
(void)argc;
(void)argv;
bret - 2;
is an expression statement and it is has no side-effect.
C does not requires any warning for this statement. The compiler is free to add or not an informative warning to say the statement has no effect. The compiler can optimize out the statement.

How to get around GCC ‘*((void*)& b +4)’ may be used uninitialized in this function warning while using boost::optional

I have code similar to the following:
#include <boost/optional.hpp>
::boost::optional<int> getitem();
int go(int nr)
{
boost::optional<int> a = getitem();
boost::optional<int> b;
if (nr > 0)
b = nr;
if (a != b)
return 1;
return 0;
}
When compiling with GCC 4.7.2 with Boost 1.53, using the following command:
g++ -c -O2 -Wall -DNDEBUG
The following warning is issued:
13:3: warning: ‘((void)& b +4)’ may be used uninitialized in this function [-Wmaybe-uninitialized]
Apparently, the root problem lies with GCC. See GCC Bugzilla
Does anyone know a workaround?
There are two levels of uninitialized analysis in gcc:
-Wuninitialized: flags variables that are certainly used uninitialized
-Wmaybe-uninitialized: flags variables that are potentially used uninitialized
In gcc (*), -Wall turns on both levels even though the latter has spurious warnings because the analysis is imperfect. Spurious warnings are a plague, so the simplest way to avoid them is to pass -Wno-maybe-uninitialized (after -Wall).
If you still want the warnings, but not have them cause build failure (through -Werror) you can white list them using -Wno-error=maybe-uninitialized.
(*) Clang does not activate -Wmaybe-uninitialized by default precisely because it's very imprecise and has a good number of false positives; I wish gcc followed this guideline too.
I have found that changing the construction of b into the following (effectively equal) code:
auto b = boost::make_optional(false,0);
eliminates the warning. However, the following code (which is also effectively equal):
boost::optional<int> b(false,0);
does not eliminate the warning.
It's still a little unsatisfactory...
Had the same issue with this piece of code:
void MyClass::func( bool repaint, bool cond )
{
boost::optional<int> old = m_sizeLimit; // m_sizeLimit is a boost::optional<int> class attribute
if ( cond )
m_sizeLimit = 60;
else
m_sizeLimit.reset();
if ( repaint )
{
if ( old != m_sizeLimit ) // warning here
doSomething();
}
}
Could not get rid of the warning with Paul Omta answer, tried to write:
boost::optional<int> old;
if ( m_sizeLimit )
old = boost::make_optional<int>(true, m_sizeLimit.value());
else
old = boost::make_optional<int>(false, 0);
...with no success.
Did not want to completely disable the warning from my code, so I found an alternative solution I would recommend: disable the warning locally:
#ifdef SDE_MOBILE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
if ( old != m_sizeLimit ) // warning here
doSomething();
#ifdef SDE_MOBILE
#pragma GCC diagnostic pop
#endif
I had a type which wasn't easily constructed so didn't want to go the boost::make_optional route. Assigning an auto variable using the return from a function got around this problem for me. So you can do:
boost::optional<Foo> Default()
{
return boost::none;
}
auto var(Default());
This will also work as a one line lambda so you can just do:
auto var([]()->boost::optional<Foo> { return boost::none; }());