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.
Related
I have the following code in c++:
#include <iostream>
typedef struct Pair{
int x;
int y;
}Pair;
void dumFun(Pair p){}
int main() {
Pair p;
if (0){
p = {1,2};
}
dumFun(p);
return 0;
}
When I compiled the code, I expected to get a warning for the line with dumFun(p) since I'm calling a function with an uninitialized variable.
What I actually want is that my Makefile will give me warning for uninitialized scalar variable issues that I see with the tool Coverity.
Tried to use flag -Wall and I thought it shows warnings for unused variables usage as this - but it doesn't.
Is there any flag to use on a Makefile that will show me warning for the line I wrote above?
You did not tell the compiler, but at least in Clang there is no warning that would catch this. -Weverything shows all possible warnings, and you can use it to find the specific parameter needed to trigger each warning. Demonstration with -Weverything shows no warnings.
I did not find a suitable parameter in GCC either.
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.
Found strange behavior that i don't understand:
std::vector<std::string> subdomainVisits(std::vector<std::string> &cpdomains)
{
// return std::vector<std::string>();
}
int main(int argc, char const *argv[])
{
std::vector<std::string> data = { "9001 discuss.leetcode.com" };
auto result = subdomainVisits(data);
return 0;
}
In this case commented return in subdomainVisits function causes Segmentation fault(use gcc version 7.3.0 (Debian 7.3.0-19) ). Uncommenting fix this problem.
Why it happens?
The behaviour of your program as written is undefined.
A non-void function must have an explicit return value on all control paths.
The only exception to this is main, which has an implicit return 0;.
A fair number of compilers will warn you of trivial cases such as the above. Do you not have the warning level set high enough? (Pass -Wall and -Wextra to "turn up" the warning level on gcc.)
Note that the C++ standard does not require a compiler to fail compilation: theoretical computer science (the halting problem) tells us that reachability is impossible to prove.
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.
When I compile this helloworld example, I get the following error repeated 4 times:
error: expected primary-expression before ‘.’ token
Here is the code:
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &hello_oper);
}
Your compiler is too old. It needs to support C99. Pass in -std=c99 if the compiler is current enough
That syntax is using a new feature of the C99 language standard called designated initializers. That feature is not part of the more common C89 standard (aka ANSI C), so a C89 compiler will give you syntax errors when you try to compile code that uses it.
To fix it, tell your compiler to use its C99 mode if it has one. For example, if you're using GCC, you should pass the -std=c99 compiler option. If your compiler doesn't support C99 at all, you'll have to either switch to a compiler that does, or refactor the code to avoid using C99 features.
Actually, gcc support newer dialects of C (or of C++). Try passing it gcc -std=c99 -Wall
Ran into a similar error, although I was unable to overcome it by adding "#define FUSE_USE_VERSION ..." as mentioned in one of the comments above.
To overcome the error, I wrote a wrapper around the fuse_operations as follows:
struct my_operations: public fuse_operations {
my_operations()
{
read = my_read;
open = my_open;
}
} operations;
main(int argc, char* argv[])
{
return fuse_main(argc, argv, &operations, NULL);
}