[[maybe_unused]] attribute not working - c++

I am trying to ignore the unused parameter warning using the new c++17 attribute [[maybe_unused]], as below.
int main([[maybe_unused]] int argc, char** argv)
{
//...
}
But I still get warning: unused parameter ‘argc’ [-Wunused-parameter] with the following additional warning.
warning: ‘maybe_unused’ attribute directive ignored [-Wattributes]
I'm using g++ (GCC) 7.2.0 with cmake-3.11.3. My compiler flags are as follows.
-std=c++17 -Wall -pedantic -Wextra -Weffc++
I remember using this attribute successfully before, but I have no idea why this is not working now. Could someone show what I am doing wrong here?

You can suppress warning about unused variable this way:
int main(int /* argc */, char** argv)
{
//...
}
or using following trick:
int main(int argc, char** argv)
{
(void)argc;
//...
}
In this case this code will work for earlier versions of C++ standard and even for pure C.

Related

Toggle warnings with fsyntax-only parameter

I have a question concerning compilation between g++ and gcc.
If I write this code:
int main(int args, char* argv[]){
return 0;
}
and compile it with: g++ -fsyntax-only -Wall -Wextra -Werror
whether the file has a .c or a .cpp extension it won't complain about unused paramaters(args and argv).
The -Wunused option will only work if I compile the file with a .c extension and gcc.
So my question is: is it possible to enable warnings with fsyntax-only parameter in all other cases ?
Thank you in advance for any reponse
No, it is not, -fsyntax-only only checks the syntax. – nos
Options to Request or Suppress Warnings:
-fsyntax-only Check the code for syntax
errors, but don’t do anything beyond that.
This anomaly appears to have been a g++ compiler bug. The OP's
observations are confirmed with g++ 5.4 but g++ 6.3 gives
the expect warnings:
$ g++-6 -fsyntax-only -Wall -Wextra -Werror test.cpp
test.cpp: In function ‘int main(int, char**)’:
test.cpp:1:14: error: unused parameter ‘args’ [-Werror=unused-parameter]
int main(int args, char* argv[]){
^~~~
test.cpp:1:31: error: unused parameter ‘argv’ [-Werror=unused-parameter]
int main(int args, char* argv[]){
^
cc1plus: all warnings being treated as errors

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.

Is there any static checking tool to check buggy code like this

I wrote the some buggy code like this:
#include "stdafx.h"
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string some_file = "afdfadf";
if(true)
{
string some_file = "/"+ some_file;
}
return 0;
}
It will throw an exception when calling std::operator+.
I guess this is because in the if statement the second some_file is an uninitialized string.
Is there any static checking tool that can help find this kind of bug?
I just tried, clang can help find the bug:
[~]$ clang bug.cpp
bug.cpp:11:29: warning: variable 'some_file' is uninitialized when used within
its own initialization [-Wuninitialized]
string some_file = "/"+ some_file;
~~~~~~~~~ ^~~~~~~~~
GCC has a warning for that case:
$ g++ t.cc -Wshadow
t.cc: In function ‘int main(int, char**)’:
t.cc:11:16: warning: declaration of ‘some_file’ shadows a previous local [-Wshadow]
t.cc:7:12: warning: shadowed declaration is here [-Wshadow]
Compilers can warn you about using a variable in its own initialization.
In GCC and CLANG, you can use -Winit-self
I am not sure about MSVC, but compiling with /W4 might give you a warning about those, too.
I was quit happy with using pclint. It will find this type of errors but it might take some time to configure it when used with an existing, larger code base.

void cast of argc and argv

I'm looking at a piece of C++ code, and the first line in the main function caught my attention:
int main(int argc, const char* argv[]) {
(void)argc; (void)argv;
...
}
Apart from this line argc and argv aren't used at all. Why is the author doing a void cast? Could it be to stop the compiler from complaining about unused variables?
"Could it be to stop the compiler from complaining about unused variables?"
yes
Yes, it's exactly to tell the compiler not to complain about unused variables.
If you set -Werror option, the compiler makes all warnings into errors, stopping compilation. It's a good practice set -Wall -Werror to check all inconsistences.
Yes, it is to prevent the compiler from complaining about unused variables. In this case a better way would be:
int main(int, char**) {
...
}
Leaving the parameters unnamed tells the compiler that they're there but are not used.

Where's g++'s VLA extension?

My question is related to this thread.
Here is the code
#include <stdio.h>
int main(int argc, char *argv[printf("Hello, world!\n")]) {}
I accidently saved it as a *.cpp file and tried to compile it with g++. But I got an error and a warning.
error: expected ',' or '...' before 'argv'
warning: second argument of 'int main(int, char*)' should be 'char **
'
I know the above code is not Standard C++ [size of an array must be a constant expression in C++] but
I always thought g++ supports Varible Length Array as an extension. Where am I wrong?
P.S : The above code gets compiled with CLang++
C:\Users\SUPER USER\Desktop>type check.cpp
#include <stdio.h>
int main(int argc, char *argv[printf("Hello, world!\n")]) {}
C:\Users\SUPER USER\Desktop>clang++ check.cpp
C:\Users\SUPER USER\Desktop>
g++ allows (again, as an extension) VLAs. I think it just doesn't allow them in parameter lists. This compiles in g++ 4.4.1.
#include <stdio.h>
int main(int argc, char *argv[])
{
char *array[printf("Hello, world!\n")];
}