Make VS compiler catch signed/unsigned assignments? - c++

The Visual Studio compiler does not seem to warn on signed/unsigned assignments, only on comparisons. For example the code below will generate a warning on the if statement but not the initial assignments.
Is there anyway to make it catch these? I'm already at W4 but thought (hoped) there may be another setting somewhere.
Thanks,
int foo(void)
{
unsigned int fooUnsigned = 0xffffffff;
int fooSigned = fooUnsigned; // no warning
if (fooSigned < fooUnsigned) // warning
{
return 0;
}
return fooSigned;
}
Update:
Quamrana is right, this is controlled by warning 4365 which appears to be off by default, even at W4. However you can explicitly enable it for a given warning level like so;
#pragma warning (4 : 4365)
Which results in;
warning C4365: 'initializing' : conversion from 'unsigned int' to 'int', signed/unsigned mismatch

You need to enable warning 4365 to catch the assignment.
That might be tricky - you need to enable ALL warnings - use /Wall which enables lots of warnings, so you may have some trouble seeing the warning occur, but it does.

You can change the level of any specific warning by using /W[level][code]. So in this case /W34365 will make warning 4365 into a level 3 warning. If you do this a lot you might find it useful to put these options in a text file and use the #[file] option to simplify the command line.

#quamrana:
There must be something beyond the /Wall option to enable warning 4365:
C:\Temp>cl /Wall /c foo.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
foo.c
foo.c(6) : warning C4018: '<' : signed/unsigned mismatch
I see that Andrew got it to work, but does anyone have an idea why it's not working here?
The Visual Studio docs indicate that it should, but I can't even get the example program in the docs to give the C4365 warning (though it does give the related C4245 warning - but that occurs with just a /W4 option anyway).

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.

How can I enable compiler warnings in Visual Studio 2019?

The reason that I ask this question is this link below:
Why can this function return a C++ int reference?
It seems that the compiler is bad at reporting mistakes such as: return a value from a function.
So I want to activate them in Visual Studio 2019, but it did not work after I set it (restart IDE) like below:
I suggest you could try to use the following method to enable warnings that are off by default:
1,#pragma warning(default : warning_number )
The specified warning (warning_number) is enabled at its default level. Documentation for the warning contains the default level of the warning.
2,#pragma warning( warning_level : warning_number )
The specified warning (warning_number) is enabled at the specified level (warning_level).
3,/Wall
/Wall enables all warnings that are off by default. If you use this option, you can turn off individual warnings by using the /wd option.
4,/wLnnnn
This option enables warning nnnn at level L.
For more details anbout warning level, I suggest you could refer to the link:https://learn.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level?view=vs-2019

Not getting c4267 warning for few lines in code

I had a task of removing all warnings in one of the project.
At one place in code I had following line.
dims[0] = children.size();
Where dims is 'int' array and children is a 'vector', so size_t is assigned to int. I am compiling this code on VS2015.
Ideally the above assignment should generate a warning
"C4267: '=': conversion from 'size_t' to 'int', possible loss of data"
But I don't get any such warning. So there are zero warnings in the code.
Now I convert warning 4267 into an error using '/we4267' and then start getting error for above lines.
I am confuse why compile didn't showed any warning in first place.
Thanking you all for your help.
I found that when /WX compiler option is added then some warnings, in my case C4267, are suppressed. Either adding compiler option /WX /Wall or removing them all together shows error/warning C4267. In my case I was getting error in other modules as there was no warning related compiler option add but the module where I didn't got C4267 warning, had compiler option /WX.
Its just that there is no documentation regarding this(or may be I was not able to find one).

How to disable warning C4927 in VS2013 Community

I'm receiving the following warning in my project:
warning C4927: illegal conversion; more than one user-defined conversion has been implicitly applied while calling the constructor 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(const _Elem *)'
with
[
_Elem=char
]
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xstring(778) : see declaration of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string'
I understand why it's happening, I'm just unable to suppress it. I've tried adding it to the Disable Specific Warnings list in my project settings, and I've also set my warning level to Turn Off All Warnings (/W0), yet the warning persists. Does anyone have any recommendations on how to hide the message?
You can control Visual Studio warnings directly in code using #pragma warning (https://msdn.microsoft.com/en-us/library/2c8f766e.aspx). If you'd like to silence the warning for a single line, you can put the following immediately before the line:
#pragma warning (suppress: 4927)
line-that-causes-warning-4927
You can also disable it from any point past the #pragma, by using 'disable' instead of 'suppress'. However, as the comments suggest, it's better to actually fix the warning, because it could be causing issues in your program.

Understanding compiler options differences in visual studio 2010 and strict C++ compliance

I am grading some homework C++ code and a student used a non-standard constructor for a vector of vectors:
vector<vector<double> > A(rows, cols);
where rows and cols are unsigned integers. The way we taught it in class is
vector<vector<double> > A(rows, vector<double>(cols));
following the fill constructor (2 in http://www.cplusplus.com/reference/vector/vector/vector/)
I am using a batch file to compile all students codes with the command line
cl /O2 /EHsc /Tp <filename>
and this command threw this error at the student line mentioned above:
error C2664: 'std::vector<std::vector<double,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>::vector(std::initializer_list<std::vector<_Ty,std::allocator<_Ty>>>,const std::allocator<std::vector<_Ty,std::allocator<_Ty>>> &)' : cannot convert argument 2 from 'unsigned int' to 'const std::vector<double,std::allocator<_Ty>> &'
with
[
_Ty=double
]
Reason: cannot convert from 'unsigned int' to 'const std::vector<double,std::allocator<_Ty>>'
with
[
_Ty=double
]
Constructor for class 'std::vector<double,std::allocator<_Ty>>' is declared 'explicit'
with
[
_Ty=double
]
But when I create a project and build it with the default parameters of MSVC 2010 it does not throw neither a warning nor an error there.
I am trying to learn what compiler option is responsible for allowing it go through without a warning in the IDE, and what I would switch it off.
I tried finding an answer in http://msdn.microsoft.com/en-us/library/2tb15w2z(v=vs.100).aspx, but I couldn't an answer.
EDIT: I think this might be helpful to others: thanks to the comments I understand now the constructor called in the IDE is the range constructor (#3 in the link above).
Here's my particular question: both methods use the same compiler with different options (one the default from the IDE, the other one is stated above). The batch file throws an error, the IDE doesn't. I need help identifying what to change in the IDE's command line arguments so that it throws the error.
UPDATE: I included the error message.
UPDATE 2: It turns out the script was being run in a computer with MSVC 2013 and that was the difference
Actually:
std::vector<std::vector<double> a( rows, columns );
is legal, or at least it was legal until C++11. It wasn't
intentionally legal, but the way the standard was worded, a
compiler was required to accept it. (I think C++11 fixed this.
Although it did so a bit too late, since doing so breaks
previously legal code.)
The rule is (or was) simple, if overload resolution on the
constructor results in the constructor
<template Iter>std::vector::vector( Iter begin, Iter end )
being chosen, and Iter deduces to an integral type, the code
must behave as if
std::vector::vector( static_cast<size_type>( begin ), static_cast<value_type>( end ) )
were called.
When you're compiling at the command line you are not using VS 2010.
Here's what I get from a VS 2010 command line compile:
C:\so-test>cl /O2 /EHsc /Tp test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
I get your error message when I compile from the VS 2013 command line (I get a similar but slightly different message from the VS 2012 command line).
I suggest that you look at the version number displayed to verify what version of the MSVC compiler you're using at the command line.
VS 2010 is 16.00.xxxx (SP1 is 16.00.40219.01)
VS 2012 is 17.00.xxxx (Update 4 is 17.00.61030)
VS 2013 is 18.00.xxxx (Update 1 is 18.00.21005.1)