Treat C4596 as Warning - c++

Using the compiler option /Wall with VS 2019 16.8.6, I'm getting a C4596;
error C4596: 'i': illegal qualified name in member declaration
for the following test program:
struct S {
int S::i;
};
int main() {}
Here's a godbolt.
The error shows up for all VS 2019 version available there with /Wall.
VS 2017 15.9.33 shows the same behavior.
VS 2015 doesn't show it.
VS 2017 and 2019 even show it when all warnings are disabled with /w, however specifically disabling 4596 really disables it.
Is this a bug or am I doing/reading something wrong?`
Is there a way to treat some, especially this, error as warning (not the other way round)?

There is a (somewhat weird) way to 'reset' this warning to 'normal' mode (i.e. to not treat it as an error); this involves using the #pragma warning(n:xxxx) directive, as shown below:
#pragma warning(4:4596)
struct S {
int S::i; // With that #pragma, this now generates 'just' a warning
};
warning C4596: 'i': illegal qualified name in member declaration
Not being party to the design of the MSVC compiler, I can't really say any more about why this happens. However, more information on adjusting its warnings using #pragma directives can be found here.
Also, possibly of interest, is that the clang-cl compiler (used from within Visual Studio) generates just a warning, with or without that pragma:
warning : extra qualification on member 'i'
[-Wmicrosoft-extra-qualification]

Related

Is there a way to tell Visual Studio to treat a warning as a warning, not an error?

In Visual Studio, warning C4996 (using a deprecated function) is treated as an error, and code that uses deprecated functions doesn't compile at all.
There are various ways to disable C4996 entirely, either suppressing it for a single line, for a translation unit, or for an entire project. But what if I want it to still raise a warning, but allow compilation while not treating it as an error?
#include <iostream>
[[deprecated]]
void deprecated_function()
{
std::cout << "I function, but have been deprecated.\n";
}
int main() {
deprecated_function();
}
This doesn't compile at all.
#include <iostream>
[[deprecated]]
void deprecated_function()
{
std::cout << "I function, but have been deprecated.\n";
}
int main() {
#pragma warning(suppress: 4996)
deprecated_function();
}
This compiles, but doesn't issue a warning at all.
Is it possible to tell Visual Studio to emit a warning, but still allow compilation, for a deprecated function? I'm thinking of refactoring purposes, where I'd like to mark a function as deprecated, identify all the places it's used, but the code still compiles at each intermediate stage where some but not all uses of the deprecated function have been replaced.
I'm compiling using Visual Studio 2019 Community 16.8.4, warning level set to /W3, "Treat Warnings as Errors" set to "No". This particular warning seems to be treated as an error if it gets emitted at all.
Found a working solution. It turns out the relevant flag is actually "SDL checks", not "Treat Warnings as Errors". Flipping it from /sdl to /sdl- causes compilation to emit a warning while still compiling.
EDIT: If I want to keep all the SDL checks on except treating Warning C4996 as an error, I can use the flag /sdl in combination with the flag /w34996, which specifies that 4996 is treated as a level 3 warning instead of an error.

[[deprecated]] results in error instead of warning in Visual Studio

According to cppreference [[deprecated("message string")]] we should be able to use the symbol but in VS results in error instead.
For example I wan't to issue a warning for ANSI methods in UNICODE builds and vice versa:
#ifdef UNICODE
[[deprecated("This method does not work well in UNICODE builds")]]
#endif // UNICODE
void f() {}
compiler doesn't let me compile, but standard says the attribute should allow usage but issue a warning message.
How to resolve this?, btw. my project is set to maximum conformance with the standard.
What ever the reason for VS going against the standard, is there a better way to issue a warning for above case?
Very much late to the party, but this cost me a couple of hours this morning.
By default, Visual Studio and the sdl (Security Development Lifecycle) compile flag treat
[[deprecated]] as an error. Whether or not you agree with this or not, that's how they do it.
To fix this go to Configuration Properties -> C/C++ -> Command Line and add /sdl /w34996
The /wX part represents the severity of the warning, and the rest is the error you want to report as a warning.
I hope this saves people some time.
I was able to get the compiler to treat [[deprecated]] as a warning by adding
/w34996
to the compiler options, as suggested in the responses in following link
https://developercommunity.visualstudio.com/content/problem/786502/cant-treat-deprecated-warning-as-warning-with-wx.html
is there a better way to issue a warning for above case?
There's no other way of warning about usage of a function than deprecation attribute in standard C++ at least that I know of.
Msvc has other alternatives such as #pragma deprecated(f), but those are not better.
How to resolve this?
Assuming you haven't configured your compiler to treat warnings as errors, you could proceed with writing a bug report to the maintainers.
I haven't tested it with Visual Studio, but in my case the following helped and probably is more generic:
On that error usually warnings are treated as errors with the compiler flag -Werror, that is automatically set in Visual Studio. That is the reason way a class or function marked with [[deprecated]] results in an error. To avoid explicitly that error and output it just as a warning, the compiler flag -Werror -Wno-error=deprecated-declarations can be set. In CMake it would look like:
add_compile_options(-Werror -Wno-error=deprecated-declarations)

Warnings not being generated in VS2017

It seems to me that VS2017 fails to catch some fairly obvious compiler warnings which older versions do not. This seems so fundamental to me that I'm guessing the problem has to be something I'm missing (e.g. some new default compiler setting, perhaps?). Has anyone else seen this?
To test this, I create a simple console application in both 2013 and 2017. The only change I made the to the project settings was to set the compiler warning level to 4 and to report warnings as errors. Below is the entirety of the source
In VS2013 this fails. In 2017, it builds just fine...
// TestWarning4127.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
int main()
{
if (true) // *** SHOULD generate warning 4127
std::cout << "Warning";
return 0;
}
Am I missing something obvious here...?
When used inside an if or while conditions the trivial constants such as 1 or true do not generate warnings in VS 2017 as described in the Compiler Warning (level4) official documentation. Excerpt from the official documentation:
The controlling expression of an if statement or while loop evaluates
to a constant. Because of their common idiomatic usage, trivial
constants such as 1 or true do not trigger the warning, unless they
are the result of an operation in an expression.
That being said it's not a warning in VS 2013 with the default warning levels of W3 either. Only with the elevated W4 settings does the VS 2013 report a warning. It was removed in VS 2017 altogether.
For comparison, the GCC does not generate the warning either:
Live example on Coliru.

No warning on deleting a forward declared pointer (Visual Studio)

Deleting forward declared pointers leads to undefined behavior.
Examples:
https://gist.github.com/jatinganhotra/4144778
https://stackoverflow.com/a/14382111/399908
However, my Visual Studio (VS2012) compiler doesn't warn me about it.
Is this an unfixed VS2012 compiler bug?
Did I disable (or never enable) the corresponding warning?
Is this specific to some project setting?
Visual Leak Detector hinted me to the problem, but is there some method (pragma, code, macro, ...) to detect this at compile time?
The respective warning is C4150.
It should be active by default and it is categorized in warning level 2 (which should be active too, since default warning level is W3 afaik).
Note: Instead of lowering the warning level, try to pragma warnings in specific cases.

Is there an alternative to suppressing warnings for unreachable code in the xtree?

When using the std::map with types that use trivial, non-throwing, copy constructors, a compiler warning/error is thrown (warning level 4, release mode) for unreachable code in xtree. This is because the std::map has a try-catch in it that helps maintain the state of the tree in the case of an exception, but the compiler figures out that the catch statement will never be called if the stored elements don't throw. These warnings can be easily suppressed with the following lines at the top of the .cpp file:
#pragma warning(push)
#pragma warning(disable:4702)
#include <xtree>
#pragma warning(pop)
Is there a way to bypass this warning/error without changing the warning level, building in debug, suppressing the warning, or using a different type in the map? Is there plans to change this in the standard library?
Update:
Maybe it is compiler specific. I am using vc7.
The error is below:
c:\program files\microsoft visual studio .net 2003\vc7\include\xtree(1116) : error C2220: warning treated as error - no 'object' file generated
c:\program files\microsoft visual studio .net 2003\vc7\include\xtree(1116) : warning C4702: unreachable code
Apparently the xtree is used by the std::map.
Unfortunately it looks like xtree is part of the underlying implementation of map in VC7, and as such there isn't much that can be done to mitigate it. It looks like it's a bug in the standard library.
Is it a possibility to use a newer compiler? I'm fairly sure there are free downloads of more recent versions of the compiler you could use, and perhaps they've fixed this issue.
If that's not an option, probably the best solution is to wrap the include of map into your own private header, complete with a comment and the #pragma+include <xtree> lines you already discovered (in addition to an include of map. This way you hide the workaround from normal use.