14

I learned that defining a function with a blank argument list is not the same as defining a function with void as the argument list. See ( Is it better to use C void arguments "void foo(void)" or not "void foo()"? ).

This misconception seems like a common one to me and I was surprised that neither gcc nor clang issued any warnings, even when I passed -Wall -Wextra -pedantic.

Why is this?

3
  • 4
    Quite a while ago, Richard Stallman sent a message to mailing list explaining that others found warnings useful, but that he did not. Likely that had some influence on the defaults. Commented Apr 16, 2015 at 1:30
  • 3
    Richard Stallman should be reminded that the compiler will be used by many individuals that do not 'automatically' write correct code. However, not having that compiler switch enabled allows programs to write code with functions being defined without a prototype, as long at the function is declared before it is called Commented Apr 16, 2015 at 3:35
  • 2
    This is a backwards compatibility issue. In old C, when a function was presented to the compiler with an empty argument list, this meant it to be undefined argument list and the compiler supposed you have not specified the number and types of arguments. To conserve this, and to be consistent with the ANSI-C requirement of checking arguments, void keyword was selected. Commented Apr 17, 2015 at 6:58

4 Answers 4

18

-Wall is actually only the beginning, and -Wextra not the end of the road by far.

Instead of quoting Mr. Stallman, and having to bite down on my tongue heavily to avoid commenting on some of his more questionable opinions (like the one referred to by Thomas Dickey), I'd rather quote the current GCC manuals, emphasis mine:

-Wall -- This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros.

-Wextra -- This enables some extra warning flags that are not enabled by -Wall.

So, if you say "all, plus extra", you're actually saying "easy ones, plus some". Better check that manual for more.

2
  • 1
    I would certainly consider unspecified arguments in a function definition to be a questionable construction. In fact, the only reason I defined functions that way was because I thought it was the same as defining them with void in the argument list. A simple warning: function defined with unspecified arguments (or even the current -Wstrict-prototypes message) would've pointed me (and many others, I'm sure) in the right direction. It's certainly easy to avoid once you do know—you can probably get your editor to do it for you en masse, too. Commented Apr 16, 2015 at 14:24
  • 3
    @BlacklightShining: The message here is, a) always run the compiler in the strictest error-checking mode possible, and b) -Wall -Wextra isn't it. ;-)
    – DevSolar
    Commented Apr 16, 2015 at 15:32
8

One of the reasons may have been the personal taste of Richard Stallman, the creator and original chief developer of gcc. Here is his message which I referred to above:

Date: Thu, 2 Sep 1999 23:19:27 -0400
Message-Id: <[email protected]>
From: Richard Stallman <[email protected]>
To: [email protected]
Subject: On using -Wall in GCC
Reply-to: [email protected]
Resent-From: [email protected]

Status: RO
Content-Length: 841
Lines: 17

I'd like to remind all GNU developers that the GNU Project
does not urge or recommend using the GCC -Wall option.

When I implemented the -Wall option, I implemented every warning that
anyone asked for (if it was possible).  I implemented warnings that
seemed useful, and warnings that seemed silly, deliberately without
judging them, to produce a feature which is at the upper limit of 
strictness.

If you want such strict criteria for your programs, then -Wall is for
you.  But changing code to avoid them is a lot of work.  If you don't
feel inclined to do that work, please don't let anyone else pressure
you into using -Wall.  If people say they would like to use it, you
don't have to listen.  They're asking you to do a lot of work.
If you don't feel it is useful, you don't have to do it.

I never use -Wall myself.

In gcc-2.7.2.3's ChangeLog.4 file, the -Wstrict-prototypes option (though present in gcc 1.42 in January 1992) is first mentioned as being distinct from -Wall:

Thu Nov 21 15:34:27 1991  Michael Meissner  (meissner at osf.org)

        * gcc.texinfo (warning options): Make the documentation agree with
        the code, -Wstrict-prototypes and -Wmissing-prototypes are not
        turned on via -Wall; -Wnoparenthesis is now spelled
        -Wno-parenthesis.
        (option header): Mention that -W options take the no- prefix as well
        as -f options.

Also, in documentation (gcc.info-3), it appeared in the section begun by this paragraph:

   The remaining `-W...' options are not implied by `-Wall' because
they warn about constructions that we consider reasonable to use, on
occasion, in clean programs.

The option itself was documented like this:

`-Wstrict-prototypes'
     Warn if a function is declared or defined without specifying the
     argument types.  (An old-style function definition is permitted
     without a warning if preceded by a declaration which specifies the
     argument types.)

The reason for the option being separate is easy to understand, given the context: this was only a few years after C had been standardized, and few programs had been converted to ANSI C. gcc had other options to help with this, e.g., -Wtraditional.

Developers of complex tools have to keep in mind compatibility. Moving options between categories is guaranteed to break some people's build scripts. For instance, gcc also has

`-Werror'
     Make all warnings into errors.

which some people use regularly. Needlessly turning on warnings that developers had earlier chosen to not use and stopping the compile as a result are not a way to maintain compatibility.

For more context on -Wall versus -Wstrict-prototypes it helps to read the entire section rather than selectively pick out text. The last paragraph in current documentation for -Wall for instance points out that -Wall is not comprehensive, and that ultimately the reason for inclusion was a matter of judgement (as in the original documentation):

Note that some warning flags are not implied by -Wall. Some of them warn about constructions that users generally do not consider questionable, but which occasionally you might wish to check for; others warn about constructions that are necessary or hard to avoid in some cases, and there is no simple way to modify the code to suppress the warning. Some of them are enabled by -Wextra but many of them must be enabled individually.

As for whose judgement that was - it would be the original developers of gcc around 1990.

8
  • 1
    Not helpful, since it does neither give good advice nor reflect the current meaning of -Wall.
    – DevSolar
    Commented Apr 16, 2015 at 11:06
  • 1
    While it is technically not an answer but just a citation it is one if one employs a few brain cells. It is also technically impossible to provide this information in a comment, so don't be silly, guys. Commented Apr 16, 2015 at 11:14
  • 1
    @PeterSchneider: The point being that whatever Mr. Stallman thinks how he implemented -Wall, it has no relation to what -Wall means today, or has any impact on whether -Wstrict-prototypes is included in it or not. It's simply OT.
    – DevSolar
    Commented Apr 16, 2015 at 13:06
  • 1
    @DevSolar Relevant history is only OT to the ignorant. Commented Apr 16, 2015 at 13:24
  • 2
    There are worse things than being ignorant (for example, quoting things out of context). Commented Apr 16, 2015 at 21:48
2

There was a lot of legacy code out there (from before void) which would throw misleading warnings. Over time the ratio of new code to old code changes so that these warnings become more useful.

2
  • 1
    Not really that much (void is standard since 1989). Commented Apr 16, 2015 at 10:51
  • 1
    I changed i to was ;-). Commented Apr 16, 2015 at 11:01
0

Because VERY many programmers use an empty parameter list for no parameters, and all those programmers would be deterred from using the warning set that contains it. Using (void) also causes problems when translating from/to C to/from another programming language.

Not the answer you're looking for? Browse other questions tagged or ask your own question.