13

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?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Blacklight Shining
  • 1,468
  • 2
  • 11
  • 28
  • 3
    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. – Thomas Dickey Apr 16 '15 at 01: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 – user3629249 Apr 16 '15 at 03:35
  • 1
    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. – Luis Colorado Apr 17 '15 at 06:58

4 Answers4

16

-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.

Community
  • 1
  • 1
DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 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. – Blacklight Shining Apr 16 '15 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 Apr 16 '15 at 15:32
7

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: <gnusenet199909030319.XAA08701@psilocin.gnu.org>
From: Richard Stallman <rms@gnu.org>
To: gnu-prog@gnu.org
Subject: On using -Wall in GCC
Reply-to: rms@gnu.org
Resent-From: info-gnu-prog-request@gnu.org

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.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • 1
    Not helpful, since it does neither give good advice nor reflect the current meaning of `-Wall`. – DevSolar Apr 16 '15 at 11:06
  • Based on that mail you could also make these arguments: 1. that RMS have no influence what the GCC developers place as default for -Wall, since he doesn't even use that flag. 2. That noone has requested that -Wstrict-prototypes to be added to the default, since RMS says he include everything that people had asked for. Though that doesn't really answer anything either. – nos Apr 16 '15 at 11:10
  • 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. – Peter - Reinstate Monica Apr 16 '15 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 Apr 16 '15 at 13:06
  • @DevSolar Relevant history is only OT to the ignorant. – Peter - Reinstate Monica Apr 16 '15 at 13:24
  • @PeterSchneider: The operational part of that phrase is "relevant". Humorous anecdote, more like. (Coming from me, who keeps quoting Stallman with regards to `#pragma`... ;-) ) – DevSolar Apr 16 '15 at 13:29
  • This, by itself, doesn't really help to answer my question. If Stallman included in `-Wall` “warnings that seemed useful, and warnings that seemed silly, deliberately without judging them,” shouldn't `-Wstrict-prototypes` have gone in with the rest? – Blacklight Shining Apr 16 '15 at 14:31
  • 2
    There are worse things than being ignorant (for example, quoting things out of context). – Thomas Dickey Apr 16 '15 at 21:48
1

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.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
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.

Ohnemichel
  • 324
  • 2
  • 9