137

I recently had to type in a small C test program and, in the process, I made a spelling mistake in the main function by accidentally using vooid instead of void.

And yet it still worked.

Reducing it down to its smallest complete version, I ended up with:

int main (vooid) {
    return 42;
}

This does indeed compile (gcc -Wall -o myprog myprog.c) and, when run, it returns 42.

How exactly is this valid code?


Here's a transcript cut and pasted from my bash shell to show what I'm doing:

pax$ cat qq.c
int main (vooid) {
    return 42;
}

pax$ rm qq ; gcc -Wall -o qq qq.c ; ./qq

pax$ echo $?
42
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • By defining main with a single `int` parameter, you invoke **Undefined Behaviour**. Anything can happen :) – pmg Feb 13 '11 at 23:40
  • 9
    Actually, I'm not sure about the UB, @pmg. ISO specifically allows for other possibilities of `main` from the standard two canonical ones. For portability, you should use one of those two but I don't think UB applies here. – paxdiablo Feb 14 '11 at 00:50
  • Hmm: in a hosted environment `main` must have one of the 2 canonical forms (2.1.2.2). But you're right @pax, in a free-standing environment, the identifier `main` is in no way special: if used as a function it can be of any type and have any number of parameters of any type. – pmg Feb 14 '11 at 19:08
  • 2
    In C99, freestanding is totally implementation defined. For hosted, section 5.1.2.2.1 states at the end "or in some other implementation-defined manner" so it requires, at a minimum, the two canonical forms but can have others as well (this would allow the UNIXy `int main (int argc, char *argv[], char *envp[]);` to be conforming). – paxdiablo Feb 14 '11 at 23:27

4 Answers4

219

It's simply using the "old-style" function-declaration syntax; you're implicitly declaring an int parameter called vooid.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 2
    This seems to be the case. If you add "vooid=42; return vooid;" to main, you also get a return value of 42. – Jeff Ames Feb 13 '11 at 22:46
  • 43
    Aargghh, you're right. If I add `-std=c99`, I get `qq.c:1: warning: type of 'vooid' defaults to 'int'`. – paxdiablo Feb 13 '11 at 22:48
70

It's valid code, because myprog.c contains:

int main (vooid) // vooid is of type int, allowed, and an alias for argc
{     
  return 42; // The answer to the Ultimate Question
} 

vooid contains one plus the number of arguments passed (i.e., argc). So, in effect all you've done is to rename argc to vooid.

Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
23

In C, the default type for a function argument is int. So, your program is treating the word vooid as int main(int vooid), which is perfectly valid code.

Chinmay Kanchi
  • 62,729
  • 22
  • 87
  • 114
20

It is only gcc -std=c89 -Wall -o qq qq.c and gcc -std=gnu89 -Wall -o qq qq.c don't emit a warning. All the other standards emit a warning about implicit type int for vooid.

int main(chart) behaves the same way as does int main (vooid).

return vooid; returns the number of command line arguments.

I tested with gcc 4.4.5 on Debian testing system.

vpit3833
  • 7,817
  • 2
  • 25
  • 25