Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

According to Section C11, Section 6.7.56.3, Function Declarators (Including Prototypes), paragraph 14 , of C99[ISO/IEC 9899:2011],

An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters. The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied. ^124)^124) See "future language directions" (6.11.6).

Section 6.11.6 , Function Declarators, states that

The the use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.

...

Code Block
bgColor#FFCCCC
langc

/* in foo.h */
void foo();

/* in foo.c */
void foo() {
  int i = 3;
  printf("i value: %d\n", i);
}

/* in caller.c */
#include "foo.h"

foo(3);

...

Code Block
bgColor#ccccff
langc

/* in foo.h */
void foo(void);

/* in foo.c */
void foo(void) {
  int i = 3;
  printf("i value: %d\n", i);
}

/* in caller.c */
#include "foo.h"

foo(3);

Implementation Details (Ambiguous Interface)

When the above compliant solution is used and foo(3) is called, the GCC compiler will issue the following diagnostic, which alerts the programmer about the misuse of the function interface.

Code Block

error: too many arguments to function ‘foo’

...

Another possible vulnerability is the leak of privileged information. In this noncompliant code example, a user with high privileges feeds some secret input to the caller that the caller then passes to foo(). Because of the way foo() is defined, we might assume that there is no way for foo() to retrieve information from the caller. However, because the value of i is really passed into a stack (before the return address of the caller), a malicious programmer can change the internal implementation and copy the value manually into a less privileged file.

Code Block
bgColor#FFCCCC
langc

/* compile using gcc4.3.3 */
void foo() {
  /* use asm code to retrieve i
   * implicitly from caller
   * and transfer it to a less privileged file */
}

...

/* caller */
foo(i); /* i is fed from user input */

...

Code Block
bgColor#ccccff
langc

void foo(void) {
  int i = 3;
  printf("i value: %d\n", i);
}

...

In C++, foo() and foo(void) have exactly the same meaning and effect, so this rule doesn't apply to C++. However, foo(void) should be declared explicitly instead of foo() to distinguish it from foo(...), which accepts an arbitrary number and type of arguments.

ISO/IEC 9899:19992011 Forward and Section 6.9.1, "Function definitions"

...