C++ : No warning for unused local constants with /W4 (MSVC) - c++

The following code was compiled with MSVC 19.29.30133.0
Given the following c++ line in a function
int foo = 0;
If the variable isn't referenced, MSCV will give you the following warning: warning C4189: 'foo': local variable is initialized but not referenced
However, if const is added in front of it, the warning disappears.
const int foo = 0; // <<--This line yields no warning with MSVC 19.29.30133.0
But this unused variable should still be removed, isn't it?
So why is it that MSVC gives no warning? Is it a bug, is there a specification for unused constants?
minimal reproduction:
int main() {
int a = 0;
const int b = 0;
return 0;
}
output:
Starting build...
cl.exe /Zi /EHsc /nologo /W4 /std:c++20 /Fe: F:\prog\INF1005C\tst\unused_constant.exe F:\prog\INF1005C\tst\unused_constant.cpp
unused_constant.cpp
F:\prog\INF1005C\tst\unused_constant.cpp(2): warning C4189: 'a': local variable is initialized but not referenced
Build finished with warning(s).

Related

What is the Visual Studio warning equivalent of GCC's -Wreturn-type?

Does Visual Studio have a warning (or warnings) that is the equivalent of GCC's -Wreturn-type?
More specifically, I am looking for a Visual Studio warning (or warnings) that will warn for instances in functions whose return types are not void where
There is a return statement with no return value; or
It is possible function execution could "fall off" the end of the function body without returning a value
I am not concerned with the other part of -Wreturn-type that warns whenever a function is defined with a return type that defaults to int.
For reference, the GCC warning options can be found here.
As pointed out in the comments, this can be done with C4033, C4716, C4715.
User n. 1.8e9-where's-my-share m. also makes a very good point about how to find MSVC warnings in general:
If you want to find out whether a warning that you want exists, just enable all [using /Wall] and test against a small piece of code. If there is a warning, congrats, you found it. If not, tough luck, there isn't any.
I test both with .c and .cpp file extensions, just in case the compiler behaved differently based on the language it is compiling (and sure enough, the behaviour was different for test 2).
None of my tests ever complain about main(), because main() is special, as it is the only function in C and C++ that defaults to returning 0 if no explicit return is provided.
All of the tests below were done using Visual Studio 2015's compiler (i.e., C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\cl.exe), and the commands were issued from the VS2015 x86 Native Tools Command Prompt.
If I am missing any test cases, please leave a comment to let me know.
Tests
C tests
Test 1 - Empty function with int return type
test_warnings.c:
int main() {}
int foo() {}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
c:\users\administrator\src\test-code\test_warnings.c(3) : error C4716: 'foo': must return a value
Test 2 - Function with int return type with a return without a value
test_warnings.c:
int main() {}
int foo() {
return;
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
C:\Users\Administrator\src\test-code\test_warnings.c(4): error C4033: 'foo' must return a value
Test 3 - Function with int return type where execution could "fall off" the end of the function
This test demonstrates that these warnings are not enough, as there is no warning or error emitted for this code.
test_warnings.c:
#include <stdlib.h>
#include <time.h>
int main() {}
int foo() {
int rand_num;
srand(time(0));
rand_num = rand();
if (rand_num > 1) {
return 0;
}
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
c:\users\administrator\src\test-code\test_warnings.c(14) : error C4715: 'foo': not all control paths return a value
C++ tests
Test 1 - Empty function with int return type
test_warnings.cpp:
int main() {}
int foo() {}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
c:\users\administrator\src\test-code\test_warnings.cpp(3) : error C4716: 'foo': must return a value
Test 2 - Function with int return type with a return without a value
test_warnings.cpp:
int main() {}
int foo() {
return;
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
C:\Users\Administrator\src\test-code\test_warnings.cpp(4): error C2561: 'foo': function must return a value
C:\Users\Administrator\src\test-code\test_warnings.cpp(3): note: see declaration of 'foo'
Test 3 - Function with int return type where execution could "fall off" the end of the function
test_warnings.cpp:
#include <stdlib.h>
#include <time.h>
int main() {}
int foo() {
int rand_num;
srand(time(0));
rand_num = rand();
if (rand_num > 1) {
return 0;
}
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
c:\users\administrator\src\test-code\test_warnings.cpp(14) : error C4715: 'foo': not all control paths return a value
Can you get this with just C4715?
I reran my tests above to see if you can get the same behaviour with just C4715, and here are my results. The command I used for testing this was
cl /nologo /W0 /we4715 <path to file>
Test
C
C++
Test 1
No warning or error
Triggers C4716 as an error, even though this is not turned on (which makes sense, as the docs for this warning say it is automatically promoted to error unless #pragma warning is used to prevent this)
Test 2
No warning or error
Triggers C2561 (a compiler error)
Test 3
Triggers C4715
Triggers C4715
This means C4715 is sufficient for C++, but not sufficient for C.
Notes
C4715 may warn if you call a function that never returns. For example, if you call a function that ends with while (true) {} or throw "error message";. To avoid this, declare the function that never returns with __declspec(noreturn), or if you are using C++11 or newer, you can use the more portable [[noreturn]] in the function declaration. (If you are calling a standard library function like exit(), the compiler will not issue a warning because it will know that function never returns.)
For some interesting related discussion, see Why does flowing off the end of a non-void function without returning a value not produce a compiler error?.

Internal compiler error (CL version: 14.27.29110)

There is code
#include <array>
struct Foo {
int bar;
};
int main() {
constexpr auto v = std::array{Foo{}};
return 0;
}
While compile whith C++17:
fatal error C1001: Internal compiler error. ... (compiler file 'msc1.cpp', line 1591)
INTERNAL COMPILER ERROR in 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\bin\HostX86\x86\CL.exe'
But this - compiles
#include <array>
struct Foo {
int bar;
};
int main() {
constexpr std::array<Foo, 1> v{Foo{}};
return 0;
}
All optimizations are disabled as described here
Is this a compiler bug?
This looks like the same bug reported on developercommunity.visualstudio.com under Regression: c++ internal compiler error in 16.7.0 with /std:c++17 (compiler file 'msc1.cpp', line 1591). I suggest you upvote that bug report, and keep an eye on it for possible resolutions.
The issue was introduced in the 16.7.0 update, and is not fixed as of the latest 16.7.5. Interim workarounds are to revert to 16.6.5, or drop /std:c++17 and use /std:default or /std:c++14 instead.

warn_unused_result attribute and returning class object

Please consider the following code:
class cls
{
};
__attribute__((warn_unused_result))
cls fn1()
{
return cls();
}
__attribute__ ((warn_unused_result))
int fn2()
{
return 1;
}
int main()
{
auto x = fn1();
(void)x;
auto y = fn2();
(void)y;
return 0;
}
When I compile this with -Wall -Wextra with gcc 5.4.0, I get a warning:
warning: ignoring return value of ‘cls fn1()’,
declared with attribute warn_unused_result [-Wunused-result]
Can somebody tell me what's wrong?
Why this warning appears for fn1 despite the x variable, and why it does NOT appear for the fn2?
Update 1: With a little help, I tried this with g++ 4.8.3 - the same result. Even more - g++ 3.3.6 produces two warnings - for fn1 and fn2.
What "fixes" the warning is...... guess what - adding a data member or a virtual member function in the class (a non-virtual function does not help). Sounds like a compiler bug to me.
Update 2: Actually adding a member or a virtual function disables the warning completely, so just calling fn1(); does NOT produce the warning anymore.

pragma warning( disable : 4700 ) not working in Visual Studio Express 2013

Compiling the following code in Release configuration with SDL checks disabled:
#include <immintrin.h>
int main()
{
const auto Set128Epi16 = []()
{
#ifdef NDEBUG
#pragma warning( push )
#pragma warning( disable : 4700 )
__m128i x = _mm_cmpeq_epi16( x,x );
x = _mm_srli_epi16( x,15 );
return _mm_slli_epi16( x,7 );
#pragma warning( pop )
#else
__m128i x = _mm_setzero_si128();
x = _mm_cmpeq_epi16( x,x );
x = _mm_srli_epi16( x,15 );
return _mm_slli_epi16( x,7 );
#endif
};
const auto xmm = Set128Epi16();
return *xmm.m128i_i32;
}
Gives the following output:
1>------ Rebuild All started: Project: pragmatic, Configuration: Release Win32 ------
1> main.cpp
1> Generating code
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1>e:\projects\pragmatic\pragmatic\main.cpp(10): warning C4700: uninitialized local variable 'x' used
1> Finished generating code
1> pragmatic.vcxproj -> E:\Projects\pragmatic\Release\pragmatic.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
Why is the compiler ignoring my #pragma in this case. I have in the past successfully used this method to suppress the same warning code.
I copied this from https://msdn.microsoft.com/en-us/library/2c8f766e.aspx
For warning numbers in the range 4700-4999, which are the ones associated with code generation, the state of the warning in effect when the compiler encounters the open curly brace of a function will be in effect for the rest of the function. Using the warning pragma in the function to change the state of a warning that has a number larger than 4699 will only take effect after the end of the function. The following example shows the correct placement of warning pragmas to disable a code-generation warning message, and then to restore it.
So you probably need to put the pragma before the start of main, or maybe before the lambda would work, but I'm not sure about that.

Why does const int change values

Im starting to learn c++ and was under the impression that by putting const is means that the value wont change but i wrote the following code:
#include<iostream>
int main()
{
const int a = 1;
a += 1;
std::cout << a << std::endl;
return 0;
}
and it prints out 2 while i thought it would have given me an error for changing a const int value.
I am using MSVS as my compiler
EDIT: I get a compiler warning saying C4530: C++ exception handler used, but unwind semantics are not enabled, specify /EHsc
It works now and gives me the correct error but does anyone know what this means
This program cannot be compiled using GNU GCC 4.8:
alioth% g++ x.cpp
x.cpp: In function ‘int main()’:
x.cpp:6:7: error: assignment of read-only variable ‘a’
a += 1;
Either your compiler is broken or you are doing something wrong (like compiling different project).
This program cannot be compiled on VS2013:
1>------ Build started: Project: SOTesting, Configuration: Release Win32 ------
1> Source.cpp
1>Source.cpp(6): error C3892: 'a' : you cannot assign to a variable that is const
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========`
The posted code:
#include<iostream>
int main()
{
const int a = 1;
a += 1;
std::cout << a << std::endl;
return 0;
}
The claim that this code compiled and produced "2" as output, is incorrect.
You can easily get the impression of something like that by inadvertently compiling a different program, or not noticing that a compilation failed and then running an existing executable.