13

As you can see in the following code, I've introduced a nested function within main():

#include <stdio.h>

int main(){
 int a=5;
 printf("%d\n",a);
 {
  int a=10;
  printf("%d\n",a);
 }
 printf("%d\n",a);

 //Nested function
 int main(int a){
 if(a>0)printf("%d\n",a--);
 return 0;
 }

 main(7);
 return 0;
}

As far as I could understand I used the -std=c99 flag in gcc to "disable" the unnecessary extensions, but I did not get any error.

gcc temp3.c -std=c99 -o temp3.out

Where have I made the mistake?

Mayank Verma
  • 633
  • 6
  • 19
  • 5
    Adding `-pedantic -Werror` should fix that. – Jonathan Leffler Aug 14 '16 at 07:12
  • Then what's the use for -std=c99 flag? – Mayank Verma Aug 14 '16 at 07:15
  • The `-std=c99` flag disables the GNU extensions that GCC thinks should be disabled — such as POSIX versions, etc. See [C Dialect Options](https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options) for the meaning of `-std=`; see [Warning Options](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options) for the meaning of `-pedantic`. – Jonathan Leffler Aug 14 '16 at 07:21

1 Answers1

20
  • Add -pedantic and -Werror to the command line.

Using GCC 6.1.0 on Mac OS X 10.11.6, with your original code in a file ped73.c and my default compilation options, I get:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition ped73.c -o ped73 
ped73.c:3:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 int main(){
     ^~~~
ped73.c: In function ‘main’:
ped73.c:3:5: error: old-style function definition [-Werror=old-style-definition]
ped73.c:13:6: error: ‘main’ takes only zero or two arguments [-Werror=main]
  int main(int a){
      ^~~~
ped73.c:13:6: error: ‘main’ is normally a non-static function [-Werror=main]
$

Renaming the nested function to nested and using int main(void), I get:

$ gcc -O3 -g-std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes 
>     -Wold-style-definition -o ped73
$

Using the extra option -pedantic I get:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -pedantic ped73.c -o ped73 
ped73.c: In function ‘main’:
ped73.c:13:2: error: ISO C forbids nested functions [-Werror=pedantic]
  int nested(int a){
  ^~~
cc1: all warnings being treated as errors
$

Then what's the point of -std=c99?

The -std=c99 flag disables the GNU extensions that GCC thinks should be disabled — such as POSIX versions, etc. See C Dialect Options for the meaning of -std=; see Warning Options for the meaning of -pedantic.

-Wpedantic
-pedantic

Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used.

Valid ISO C and ISO C++ programs should compile properly with or without this option (though a rare few require -ansi or a -std option specifying the required version of ISO C). However, without this option, certain GNU extensions and traditional C and C++ features are supported as well. With this option, they are rejected.

-Wpedantic does not cause warning messages for use of the alternate keywords whose names begin and end with __. Pedantic warnings are also disabled in the expression that follows __extension__. However, only system header files should use these escape routes; application programs should avoid them. See Alternate Keywords.

Some users try to use -Wpedantic to check programs for strict ISO C conformance. They soon find that it does not do quite what they want: it finds some non-ISO practices, but not all—only those for which ISO C requires a diagnostic, and some others for which diagnostics have been added.

A feature to report any failure to conform to ISO C might be useful in some instances, but would require considerable additional work and would be quite different from -Wpedantic. We don't have plans to support such a feature in the near future.

Where the standard specified with -std represents a GNU extended dialect of C, such as ‘gnu90’ or ‘gnu99’, there is a corresponding base standard, the version of ISO C on which the GNU extended dialect is based. Warnings from -Wpedantic are given where they are required by the base standard. (It does not make sense for such warnings to be given only for features not in the specified GNU C dialect, since by definition the GNU dialects of C include all features the compiler supports with the given option, and there would be nothing to warn about.)

And there's also a different option that gives pedantic errors:

-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. This is not equivalent to -Werror=pedantic, since there are errors enabled by this option and not enabled by the latter and vice versa.


There are multiple questions about which GCC compiler options to use, including:

and no doubt there are many others that could be added to that list. Basically, the default options I use ensure that functions are declared before they are used (or, are defined as a static function before they are used), and that the function declarations have full prototypes — no empty parentheses () — and use the -Wall and -Wextra to spot a number of other routine problems, including mismatches between format strings and arguments to the printf() and scanf() families of functions.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • This is something that I stumbled on when I added `-pedantic` to my default compile string. The only place I've found it documented is [**Language Standards Supported by GCC**](https://gcc.gnu.org/onlinedocs/gcc/Standards.html) – David C. Rankin Aug 14 '16 at 07:23
  • 1
    Might want to emphasise and explain your usage of `-Wall -Wextra`. These cause the compiler to report various concerns that it is not configured to by default. Not all of these are pertinent to avoiding gcc extensions, but they are concerns that either indicate bugs (suspicious conversions, etc) or which won't work as intended with other compilers. If `-Werror` does not cause termination on warning, a deliberate policy of "don't accept code that triggers warnings" will. – Peter Aug 14 '16 at 07:32
  • 2
    This still doesn't disable gnu extensions, except those that are related to syntax. E.g. type punning via unions still works and is allowed even in this mode – Swift - Friday Pie Feb 22 '19 at 07:56
  • I don't see how this answers the question. Turning all warnings into errors is not the same as disabling GNU extensions. Imagine my work as a teacher, trying to automate parts of the exercise submissions, not wanting to see GNU extensions used, but also NOT wanting to stop the compilation for other warnings. – Tammi Mar 10 '21 at 11:42
  • You can't completely stop the GNU extensions. No mechanism is provided to do so. This is as close as you can get. – Jonathan Leffler Mar 10 '21 at 12:44