1

I'm studying Learn to Code with C by Simon Long. https://www.raspberrypi.org/magpi-issues/Essentials_C_v1.pdf on page 20 there is this simple program:

#include <stdio.h>
void main (void)
 {
  int a = 0;
  while (a < 5)
{
  printf ("a is equal to %d\n", a);
  a++;
}
  printf ("a is equal to %d and I've finished\n", a);
}

But when I compile this I get this compiler error:

while-loop.c:3:1: warning: return type of 'main' is not 'int'
  [-Wmain-return-type]
void main(void)
^
while-loop.c:3:1: note: change return type to 'int'
void main(void)
^~~~
int
1 warning generated.

Why is this? It seems that the author's compiler does not give error for this. Why the discrepancy?

When I change

void main (void) 

to

int main (void)

it compiles fine.

zeynel
  • 177
  • 1
  • 1
  • 12

1 Answers1

3

Per 5.1.2.2.1 Program startup, paragraph 1 of the C standard (bolding mine):

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

     int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

     int main(int argc, char *argv[]) { /* ... */ }

or equivalent; or in some other implementation-defined manner.

While void main() does fit in "or in some other implementation-defined manner", in my opinion a particular implementation-specific extension such as that doesn't belong in a beginner's text without at least some explanation as it will only lead to confusion later.

At least find a book that doesn't make the eyes hurt so much.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • what's the difference btw `int main(void)` and `int main()` sir? – Soner from The Ottoman Empire Apr 29 '19 at 16:36
  • 3
    `int main(void)` - takes no parameters. `int main()` - takes unspecified number of parameters. Only the former should be used for function definitions. – Eugene Sh. Apr 29 '19 at 16:37
  • @EugeneSh. thanks firstly, what's the wrong(s) with the latter one sir? Even gcc accepts it w/o any error or warning. – Soner from The Ottoman Empire Apr 29 '19 at 16:39
  • 1
    @snr Take a look at this question: https://stackoverflow.com/questions/22073893/c-unspecified-number-of-parameters-void-foo – Eugene Sh. Apr 29 '19 at 16:40
  • 1
    @snr: Unless the compiler documentation explicitly lists it as a valid signature, `void main()` results in *undefined behavior*, meaning that it's considered erroneous code, but the compiler is not required to handle it in any particular way. There are some (admittedly old and/or oddball platforms) where using `void main()` may result in code that crashes on startup. Newer compilers tend to warn about it, but strictly speaking they are not *required* to. That's the problem with a lot of undefined behavior, you may not get a warning about it. – John Bode Apr 29 '19 at 17:02
  • @JohnBode thanks for your answer sir, but my question was interested in "formal parameters" of the main() function having the return type of _int_. – Soner from The Ottoman Empire Apr 29 '19 at 17:12
  • 1
    @snr - In a function *definition* (where you specify the function body), an empty parameter list means the same thing as a parameter list of `void` - the function takes no arguments. So `int main(void) { ... }` and `int main( ) { ... }` both mean the same thing. In a function *declaration* (where you only specify the function name and argument list), an empty parameter list means the function takes an *unspecified* number of arguments, so `int foo();` and `int foo(void);` mean *different* things. As a matter of style, always use `void` instead of an empty parameter list for no arguments. – John Bode Apr 29 '19 at 17:25
  • @JohnBode w.r.t. *an empty parameter list means the same thing as a parameter list of void* - Are you sure? https://ideone.com/vVPGNC vs https://ideone.com/961XJa – Eugene Sh. Apr 29 '19 at 17:47
  • 1
    @EugeneSh.: As part of a function *definition*, yes. 6.7.6.3/14: "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." – John Bode Apr 29 '19 at 17:58
  • 1
    @EugeneSh.: Now, using an empty parameter list as opposed to `void` means the function declaration/definition is not a *prototype*, so no checks are made on the numbers and types of arguments in a function call. Hence why your second example compiled. – John Bode Apr 29 '19 at 18:04
  • @JohnBode would you mind showing your bolded saying by using ideone, with a small example? – Soner from The Ottoman Empire Apr 29 '19 at 18:47