Why const keyword without identifier in function parameter compiles? - c++

As I was playing with the C++ syntax, I coded something I thought wouldn't compile.
The following code is simplified to isolate the problem:
void foo(const) {} //why doesn't the compiler flag this line as error?
int main() {}
I compiled the above source code for C++ on MinGW's g++ compiler, and it did so without any warning or error.
Out of curiosity, I would like to know if there is any intention behind why const is allowed without a following identifier inside a function parameter.
Or is this perhaps a bug?
EDIT: Take a look at this and witness the mystery yourself.

You are probably running your compiler without enabling useful warnings. Many compilers emit only the diagnostics that the Standard requires them to, unless you specifically ask for more:
g++ -std=c++17 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds -Weffc++ -c -o 16019202.o 16019202.cpp
16019202.cpp:1:10: error: ISO C++ forbids declaration of ‘parameter’ with no type [-fpermissive]
void foo(const) {} //why doesn't the compiler flag this line as error?
^~~~~
(That's with GCC 6.3.0 on Debian).

Related

Ensure that g++ does not compile a program using features added in newer versions of C++

Compiling with the flag -std=c++14 compiles programs which use features implemented in newer versions of C++ as well, issuing a warning like the following:
warning: inline variables are only available with -std=c++17 or -std=gnu++17
I don't want g++ to compile the program in this situation and do not know why it does in the first place.
I found out that adding the flag -Werror converts the above warning to an error, ensuring that the program does not compile but I am not sure whether that is the recommended way to do so.
To provoke compiler errors specifically for the use of language features that are legal only
in C++ standards later than your chosen one, the best-targeted diagnostic option
is probably -pedantic-errors, which is documented
-pedantic-errors
Give an error whenever the base standard (see -Wpedantic) requires a diagnostic, in some cases where there is undefined behavior at compile-time and in some other cases that do not prevent compilation of programs that are valid according to the standard...
[my emphasis]
The "base standard" here is the C++ standard named by the specified or default value of -std=... (or if that one is a GNU dialect like gnu++14, then it is the C++ standard on which that dialect is based).
If you compile source code with, say, std=c++14 that uses a construct first legalised in C++17, then that code is ill-formed per the C++14 standard and a diagnostic is required.
The addition of -pedantic-errors to -std=c++14 will therefore oblige the compiler to diagnose the C++17 innovations as errors.
E.g, without -pedantic-errors
$ cat foo.cpp
struct foo
{
inline static const int value = 42;
};
$ g++ -std=c++14 -Wall -Wextra -pedantic -c foo.cpp
foo.cpp:3:5: warning: inline variables are only available with ‘-std=c++17’ or ‘-std=gnu++17’
3 | inline static const int value = 42;
| ^~~~~~
And with -pedantic-errors
$ g++ -std=c++14 -Wall -Wextra -pedantic-errors -c foo.cpp
foo.cpp:3:5: error: inline variables are only available with ‘-std=c++17’ or ‘-std=gnu++17’
3 | inline static const int value = 42;
| ^~~~~~
-pedantic-errors will make the compiler more fussy about C++14 conformity than
std-c++14 by itself, or with -Werror. But I guess you won't object to that. And you can make an unconstrained
choice as to whether you also practice the blanket discipline of compiling with zero warnings (-Werror)

How to force compiler error when no value is explicitly returned from function

One of the most common errors I make is that I forget to return the result from a method/function, and the compiler doesn't complain.
How can I make GCC raise a compilation error if no result is returned? (these are usually trivial situations, where there is no return statement in a method)
Use -Wreturn-type (I would recommend at least -Wall, maybe also -Wextra). It gives a warning when you don't return a value; you can use -Werror to make it into an error.
Compile with the -Wall -Werror flags. This will produce an error:
error: no return statement in function returning non-void
-Wall by itself only produces a warning.
I recommend compiling with -Wextra too.
g++ -Werror main.cpp -o main Warnings as errors! and -Wall helps too

gnu gcc How to suppress warning: ‘typedef’ was ignored in this declaration [enabled by default]

I am using GNU gcc 4.6.2 on Fedora 16. I am writing an application using a 3rd party API, after compilation, I got a lot warnings.
warning: ‘typedef’ was ignored in this declaration [enabled by default]
Just wondering how can I suppress this? I compile my program with -Wall flag.
In this doc, http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html, it mentioned something like -Wunused-local-typedefs.
I have tried -Wno-unused-local-typedefs, but doesn't work.
Thanks.
-Wno-unused-local-typedefs works in GCC 4.8.
gcc allows you to specify that certain library include paths should be treated as system libraries with the -isystem switch which allows those headers special treatment with respect to the flags you use on the rest of your code. So for example if you have unused local typedefs from using certain Boost libraries in test.cpp (I ran into this using including the Boost signals2 library recently)
g++ -o test{,.cpp} -Wall -Wextra -Werror -I /usr/local/boost-1.55.0/include -L /usr/local/boost-1.55.0/lib
and the above does not build cleanly try the following
g++ -o test{,.cpp} -Wall -Wextra -Werror -isystem /usr/local/boost-1.55.0/include -L /usr/local/boost-1.55.0/lib
which will (provided the warnings coming from the Boost libraries you are including in test.cpp are your only problem of course).
According to the gcc-source-code(gcc/cp/decl.c:4108):
warning (0, "%<typedef%> was ignored in this declaration");
There is no command line flag(that is what the 0 stands for) to suppress this warning in gcc 4.6.2.
As -Wunused-local-typedefs is part of -Wall, make sure you don't have -Wall after -Wno-unused-local-typedefs. If you do, -Wall just turns the option back on again.
In C++17, you should use [[maybe_unused]].
For an overview of all attributes, please see http://en.cppreference.com/w/cpp/language/attributes.
Proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0212r0.pdf
(sorry, I could't post an example, as it's considered as badly indented by stackoverflow)
This GCC warning means that your typedef maybe duplicated and you should remove typedef keyword instead. For example:
typedef enum class Something {
THING1,
THING2,
} Something;
This code above is type duplicate, because enum class is defined as type already. So you must remove typedef keyword as well as Something at the end too!

gcc error with Python C API code - "ISO C++ forbids casting between pointer-to-function and pointer-to-object"

The following code fragment does nothing, but illustrates the problem. It was extracted from some Boost Python code, which uses the Numpy C API. This was tested with the backport of a gcc 4.7 snapshot from Debian unstable to squeeze.
#include <boost/python/object.hpp>
#include <numpy/arrayobject.h>
int main(void)
{
PyObject* obj=0;
npy_int64 val;
PyArray_ScalarAsCtype(obj, &val);
return 0;
}
I'm compiling like this.
g++-4.7 -o warn.o -c -isystem /usr/include/python2.6 -fdiagnostics-show-option -ftemplate-depth-100 -fno-strict-aliasing -ansi -pedantic -Wextra -Wall -Werror -Wno-unused-function -Wc++0x-compat -g -O3 -std=c++11 -I/usr/include/python2.6 warn.cc
warn.cc: In function 'int main()':
warn.cc:8:3: error: ISO C++ forbids casting between pointer-to-function and pointer-to-object [-Werror]
cc1plus: all warnings being treated as errors
The problem is the -pedantic and the PyArray_ScalarAsCtype line of code. Without -pedantic the following compiles without error
g++-4.7 -o warn.o -c -isystem /usr/include/python2.6 -fdiagnostics-show-option -ftemplate-depth-100 -fno-strict-aliasing -ansi -Wextra -Wall -Werror -Wno-unused-function -Wc++0x-compat -g -O3 -std=c++11 -I/usr/include/python2.6 warn.cc
g++-4.7 -o warn warn.o -L/usr/lib/python2.6/config -lpython2.6 -lboost_python
Note: I added the =0 to suppress an uninitialized warning. Like I said, the code doesn't do anything.
I'd like to either suppress or remove the warning and keep the -pedantic flag. From what I've read, there is no error as such here, but this falls within some disputed section of the standard. I don't really understand the issue, or how it pertains to this line of code. The new gcc diagnostics allow one to selectively suppress warnings in a section of code, but they require you to know what specific flag is triggering the warning, and I don't know. Without the -Werror flag I get
warn.cc:8:3: warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [enabled by default]
In Standard C++, you cannot convert between, say, an int* and int(*)(). Likely, this is what's happening under the hood in your implementation. Most platforms allow it, but not all.
Of course, there is nothing illegal about any library only executing on platforms where it is legal.

Why does my C++0x code fail to compile if I include the "-ansi" compiler option?

I've come across a really weird error that only pops up if I use the ansi flag.
#include <memory>
class Test
{
public:
explicit Test(std::shared_ptr<double> ptr) {}
};
Here's the compilation, tested with gcc 4.5.2 and 4.6.0 (20101127):
g++ -std=c++0x -Wall -pedantic -ansi test.cpp
test.cpp:6:34: error: expected ')' before '<' token
But compiling without -ansi works. Why?
For the GNU C++ compiler, -ansi is another name for -std=c++98, which overrides the -std=c++0x you had earlier on the command line. You probably want just
$ g++ -std=c++0x -Wall minimal.cpp
(-pedantic is on by default for C++, so it's unnecessary to say it again. If you want pickier warnings, try adding -Wextra.)
std::shared_ptr doesn't exist in c++98. Try these changes:
#include <tr1/memory>
...
explicit Test(std::tr1::shared_ptr<double> ptr) {}
Um, because there is not yet an ANSI standard for C++0x? The ANSI flag checks for conformance with existing standards, not future ones.