gcc/g++ are giving different response to empty main function - c++

I am using
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
If I make a cpp and c file that contains only
int main(const int argc, const char *const argv[])
{
}
and compile it with g++ -Wall test_warnings.cpp I get no warning.
If I compile it with gcc -Wall test_warnings.c I get the warning you would expect:
test_warnings.c: In function ‘main’:
test_warnings.c:4:1: warning: control reaches end of non-void function [-Wreturn-type]
The same behavior is exhibited if -Wreturn-type is used instead of -Wall.
Why isn't g++ giving me a warning that the return is missing?

Because C and C++ are different languages.
In C++, reaching the end of main() without executing a return statement is equivalent to executing return 0;.
In C, as of the 1990 ISO standard, falling off the end of main() returns an undefined status to the calling environment.
C99 changed this, essentially adopting the C++ rule -- but gcc doesn't implement C99 by default. (Try compiling with -std=c99.)
In any case, it can't hurt to add a return 0; statement to the end of main().

Related

How to get the compiler to warn that this is an invalid bool?

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?

G++ -Wshadow doesn't warn about static member shadowing

Once again I lost some hours because of mere stupidity which could have been recognized by the compiler. This is the source code in question:
class f {
static int mVar;
int g(int x) { int mVar=3; return x+mVar; }
};
int f::mVar = 1;
The problem is, that I accidentally added int in front of mVar. When I compile this with: g++ -c -Wall -Wextra -Wshadow shadowtest.cpp I don't get any warning, about the local mVar shadowing the static member mVar.
But if I don't declare the member variable to be static, then g++ correctly issues a warning:
class f {
int mVar;
f(int rVar) : mVar(rVar) {};
int g(int x) { int mVar=3; return x+mVar; }
};
compile with g++ -c -Wall -Wextra -Wshadow shadowtest2.cpp gets:
shadowtest2.cpp:5:24: warning: declaration of ‘mVar’ shadows a member of ‘f’ [-Wshadow]
int g(int x) { int mVar=3; return x+mVar; }
^
shadowtest2.cpp:3:9: note: shadowed declaration is here
int mVar;
^
Tested with g++ 4.9.2 and 5.2.1.
Is this correct behavior or a bug? Why?
Edit: I filed a bug report here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68374
Edit 2018-02-12: Doesn't warn in these versions:
g++-4.9 (Debian 4.9.4-2) 4.9.4
g++-5 (Debian 5.4.1-4) 5.4.1 20161202
g++-5 (Debian 5.5.0-8) 5.5.0 20171010
g++-6 (Debian 6.3.0-18) 6.3.0 20170516
g++-6 (Debian 6.4.0-12) 6.4.0 20180123
g++-7 (Debian 7.2.0-16) 7.2.0
g++-7 (Debian 7.3.0-3) 7.3.0
but successfully warns in:
g++-8 (Debian 8-20180207-2) 8.0.1 20180207 (experimental) [trunk revision 257435]
This looks potentially like a bug given the description of -Wshadow in the gcc documentation:
Warn whenever a local variable or type declaration shadows another variable, parameter, type, class member (in C++), or instance variable (in Objective-C) or whenever a built-in function is shadowed. Note that in C++, the compiler warns if a local variable shadows an explicit typedef, but not if it shadows a struct/class/enum.
Especially considering that clang warns for this case. This is basically a quality of implementation issue since this is not ill-formed code. I would file a bug report. Most likely they they will provide a rationale for not warning in this case or they will eventually fix the warnings.
It looks like gcc used to warn about this case if we go all the way back to version 4.5.4 see it live.

Missing "missing sentinel" warning for exec in C++11

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.

Force compile error in G++ for undeclared functions

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.

Forcing GCC 4.x to treat -Wreturn-type as an error without enabling -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.