GCC will helpfully warn you if you forget to include the NULL sentinel at the end of a call to one of the exec(3) functions:
#include <unistd.h>
int main(int argc, char **argv)
{
execlp("test", "test", "arg1");
}
Sample compiler output for GCC 4.8:
$ g++ test.cc -Wformat
test.cc: In function ‘int main(int, char**)’:
test.cc:4:32: warning: missing sentinel in function call [-Wformat=]
execlp("test", "test", "arg1");
^
$
However, if you compile in C++11 mode, no diagnostic is printed:
$ g++ test.cc -std=c++11 -Wformat
$
Why is this warning not available in C++11? Is there any way to get it back?
execlp is not a standard C function. For the compiler to recognize it as a "standard" function, for which it knows what the arguments should look like, you need -std=gnu++11 instead of -std=c++11. Note that the default is -std=gnu++98. Glibc could improve the situation by specifying the sentinel attribute on the declaration of execlp.
Related
We just got burnt by a typo: "constexpr bool maxDistance=10000;"
Both gcc and clang compile this with no warning.
The real error here is that the variable shouldn't have been of type bool, but should have been an integer type instead.
How can we ensure we get a compiler warning in future?
#include <iostream>
constexpr bool number = 1234;
int main(int argc, char* argv[])
{
std::cout << number + 10000 << std::endl; // prints 10001.
return number;
}
The error here is that the variable is declared with the wrong type, however neither clang nor gcc give a warning.
gcc -Wall -std=c++14 test.cpp -lstdc++
clang -Wall -std=c++14 test.cpp -lstdc++
(using gcc 5.4.0 and clang 3.8.0)
Note: I've since learnt about a possible compile flag: -Wint-in-bool-context however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?
You should use direct list initialization syntax, it prohibits narrowing:
constexpr bool number{1234}; // error: narrowing conversion of '1234' from 'int' to 'bool' [-Wnarrowing]
I've discovered that gcc has a flag '-Wint-in-bool-context' however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?
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
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.
I've installed GCC 4.8 using this method on my Mac. Everything works fine except that for certain functions like scanf and printf, the program compiles fine without any error/warning even when I did not include their respective libraries like cstdio. Is there any way that I can do to for GCC (more specifically G++, as I am dealing with C++ programs) to throw an error when such code is being fed? The following code compiles fine on my machine:
#include <iostream>
//Notice I did not include cstdio but my program uses printf later on
int main()
{
printf("Hello World!\n");
return 0;
}
I was given the suggestion to use -Werror-implicit-function-declaration -Werror or -Wall -Werror, but they don't work.
-Wimplicit-function-declaration -Werror works for me. There must be some other problems as well.
h2co3-macbook:~ h2co3$ cat baz.c
#ifndef BAILZ_OUT
#include <stdio.h>
#endif
int main()
{
printf("Hello world!\n");
return 0;
}
h2co3-macbook:~ h2co3$ gcc -o baz baz.c -Wimplicit-function-declaration -Werror
h2co3-macbook:~ h2co3$ echo $?
0
h2co3-macbook:~ h2co3$ gcc -o baz baz.c -Wimplicit-function-declaration -Werror -DBAILZ_OUT
cc1: warnings being treated as errors
baz.c: In function ‘main’:
baz.c:7: warning: implicit declaration of function ‘printf’
baz.c:7: warning: incompatible implicit declaration of built-in function ‘printf’
h2co3-macbook:~ h2co3$ echo $?
1
h2co3-macbook:~ h2co3$
The reason you get no diagnostic is that <iostream> is including the declaration of printf, which it seems to do with the c++0x or c++11 flags.
This compiles on a gcc 4.8 snapshot with the following command line:
g++ -Wall -Wextra -pedantic-errors -std=c++0x
#include <iostream>
int main()
{
printf("Hello World!\n");
return 0;
}
If you comment out the <iostream> include, or remove the C++11 compilation flags, you get an error.
impl_decl.cpp: In function 'int main()':
impl_decl.cpp:5:28: error: 'printf' was not declared in this scope
From the Annex C/Compatibility of the C++ standard from 2003:
C.1 C++ and ISO C:
C.1.3 Clause 5: expressions [diff.expr]
5.2.2
Change: Implicit declaration of functions is not allowed
Rationale: The type-safe nature of C++.
That means that implicit declarations must cause a compilation error in C++.
I'm guessing you're compiling not C++ files, but C files and you're doing that in some pre-C99 mode, which is the default in gcc. The C standard from 1999 disallows implicit declarations as well.
You may want to pass to gcc a combination of these options: -std=c99 -Werror.
Suppose we have the following code:
#if !defined(__cplusplus)
# error This file should be compiled as C++
#endif
#include <stdio.h>
#include <string>
//#define USE_CXX_CLASS
#ifdef USE_CXX_CLASS
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}
std::string GetSomeString()
{
// case #1
}
};
#endif // USE_CXX_CLASS
int foo()
{
// case #2
}
int
main (int argc, char *argv[])
{
(void)argc;
(void)argv;
#ifdef USE_CXX_CLASS
SomeClass someInstance;
someInstance.GetSomeString();
#endif // USE_CXX_CLASS
foo();
return 0;
}
And suppose that it were to be compiled the C++ compiler (and not the C compiler) from GCC version 4.2.1 with the options -Wreturn-type -Werror=return-type. If the above code is compiled as is without first uncommenting the //#define USE_CXX_CLASS line above, then you will see a warning but no error:
.../gcc-4.2.1/bin/g++ -g -fPIC -Wreturn-type -Werror=return-type test.cpp -c -o test.o
test.cpp: In function 'int foo()':
test.cpp:26: warning: control reaches end of non-void function
But if the //#define USE_CXX_CLASS line is uncommented, then the warning is treated as an error:
.../gcc-4.2.1/bin/g++ -g -fPIC -Wreturn-type -Werror=return-type test.cpp -c -o test.o
test.cpp: In member function 'std::string SomeClass::GetSomeString()':
test.cpp:18: error: no return statement in function returning non-void [-Wreturn-type]
gmake: *** [test.o] Error 1
Yes, one is a non-member function (case #2), and the other is a C++ function (case #1). IMO, that should not matter. I want both conditions treated as an error, and I don't want to add -Werror or -Wall at this point in time (probably will do so later, but that is out of scope of this question).
My sub-questions are:
Is there some GCC switch that I am missing that should work? (No I do not want to use #pragma's.)
Is this a bug that has been addressed in a more recent version of GCC?
For reference, I have already poured through other similar questions already, including the following:
Why does flowing off the end of a non-void function without returning a value not produce a compiler error?
C question: no warning?
Is a return statement mandatory for C++ functions that do not return void?
It has been fixed, it works well with g++ 9.3: both member functions and free functions are treated as error with -Wall -Werror=return-type
I do see an error even w/o the USE_CXX_CLASS flag. i.e. g++ is consistent with the error for both class member functions and non member functions.
g++ (GCC) 4.4.3 20100127 (Red Hat 4.4.3-4)
It seems to me that what you need is a shell script wrapper around gcc.
Name it something like gcc-wrapper and g++-wrapper.
In your Makefile set CC and CXX to the wrappers.
Have the wrapper invoke GCC and pipe its output to another program which will search for your desired warning strings.
Have the search program exit with an error when it finds the warning.