3

I've recently come across a C program in which the main function only took a single argument. Is this legal in C89? gcc didn't seem to have any problems with it.

What I think happens is that the signature is ignored and main is called as main(int,char**) anyways, but I'm not sure.

It looks like this in the program: main(argc) { ... }

Cubic
  • 14,902
  • 5
  • 47
  • 92

2 Answers2

5

According to the C89 standard, it is not legal. From section 2.1.2.2 Hosted environment:

The function called at program startup is named `main`. The implementation
declares no prototype for this function. It can be defined 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[]) { /*...*/ }

The C99 standard states the same in section 5.1.2.2.1 Program startup.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • The standard is all fine and dandy, but I think what really matters is does it work for the compiler he's targeting? Does anyone here have a compiler where the above code DOESN'T work? – Richard J. Ross III Jun 29 '12 at 13:38
  • @RichardJ.RossIII, I agree with you. However, the OP did explictly ask _Is this legal C89_? FWIW, Microsoft compilers VC9 and VC10 compiled fine. – hmjd Jun 29 '12 at 13:41
  • Nope, you were right, that was the question. I already knew it worked, I just didn't know if it was legal. – Cubic Jun 29 '12 at 13:57
  • You left off the last bit from that section - "or in some other implementation-defined manner." An implementation is free to define `main` in a manner other than what's specified in the standard *as long as it documents the additional signature(s)*. Having said that, I see nothing in the GCC manual that indicates this is a legal signature, so the behavior is *undefined*, so there's no requirement for the compiler to issue a diagnostic for it. Also, we're assuming this code is meant for a **hosted** implementation; if it's meant for a freestanding implementation, then all bets are off. – John Bode Jun 29 '12 at 13:58
  • @JohnBode, I don't see that in the C89 standard, but I do see it in the C99 standard but there it is qualified with _Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on_. It does not state that an implementation is free to change the signature. – hmjd Jun 29 '12 at 14:04
  • @hmjd In what I have, it's: "or equivalent;9) or in some other implementation-defined manner." where `9)` is the footnote you quoted. The same in n1570. So however it was meant, one _can_ read the part after the semicolon as separate from the "or equivalent" with the footnote. I wish they had been more unambiguous. – Daniel Fischer Jun 29 '12 at 14:15
  • @hmjd - it was added in C99. And that footnote applies to the second standard definition `int main(int argc, char *argv[]);`. – John Bode Jun 29 '12 at 14:16
3

Yes, it works, but it is useless.

Remember that in C, any variable that doesn't have a type specified defaults to int, so that means that the function expands to this:

int main(int argc) {
    ...
}

Which is legal in C89. Most of the time, however, if you want to know the number of arguments sent to a program, you probably want the contents of those arguments, so this is mostly useless.

However, GCC (when compiled with -Wall) gives me a warning:

Only one parameter on 'main' declaration.

It's just saying that this code is pretty much useless.

However, technically, as @hmjd noted, this is illegal, in that it is undefined behavior. However, in most implementations of C that I have came across, when you pass extra parameters to a function, they are just ignored for the most part. So, unless you are on a system where it matters if you overflow the amount of variables sent to a function, you should be fine.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • 1
    I think the phrasing matters here, the code may *compile* with GCC and several others compilers, but it is not *legal* according to the C89 standard. – strnk Jun 29 '12 at 13:32
  • This was used in an obscured C program. I knew it worked (kinda), I was more interested in knowing whether that was actually defined behavior (I personally think that using illegal code in obscured programs is cheating). – Cubic Jun 29 '12 at 13:56
  • The behavior is ***undefined***; the code is erroneous, but the compiler is under no obligation to do anything in particular about it. It may halt translation and issue a diagnostic, or it may translate the code without any diagnostics, or anything in between. I interpret ***illegal*** to mean that the compiler *must* issue a diagnostic and cease translation, which is not the case here. – John Bode Jun 29 '12 at 14:07