Reputation: 2728
Recently I got a question when writing a program for file opening.
Let me explain my question clearly. Here I'm taking open
call as an example.
To create a file:
open("file_name", O_CREAT, 0766); //passing 3 parametrs
To open a file:
open("file_name", O_RDWR); //only 2 arguments.
Then I clearly observed this point and it also works for main()
too.
main(void) //worked
main(int argc, char **argv); //worked
main(int argc) //worked and it's doesn't give an error like "too few arguments".
main() //worked
So how we can create these optional arguments? How exactly can the compiler validate these prototypes? If possible, please write an example program.
Upvotes: 6
Views: 21790
Reputation: 477150
The open
function is declared as a variadic function. It will look something like this:
#include <stdarg.h>
int open(char const * filename, int flags, ...)
{
va_list ap;
va_start(ap, flags);
if (flags & O_CREAT)
{
int mode = va_arg(ap, int);
// ...
}
// ...
va_end(ap);
}
The further arguments are not consumed unless you have indicated that they do in fact exist.
The same construction is used for printf
.
The manual doesn't always make this explicit, since the only possible two signatures are (char const *, int)
and (char const *, int, int)
, so there's little point in revealing that you the function actually accepts variable arguments. (You can test this by trying to compile something like open("", 1, 2, 3, 4, 5, 6)
.)
Upvotes: 7
Reputation: 754130
In all cases, a varargs function must be able to determine somehow, from the fixed arguments, how many variable arguments there are. For example, the printf()
family of functions use the format string to determine the number and types of the arguments. The execl()
function uses a sentinel (null pointer) to mark the end of the argument list. It would be possible to use a count instead of a sentinel (but if you're going to do that, the chances are that a count and an array in a non-varargs function would work as well as, if not better than, a count and a list of arguments). The open()
function uses one of the flag bits to determine whether the mode should be present — see Kerrek SB's answer.
The main()
function is a special case. The implementation (compiler) is prohibited from declaring a prototype for it, and must accept at least the two forms:
int main(int argc, char **argv);
int main(void);
or their equivalents. It may accept other forms too; see What's the use of the third environment variable in the C main()
? for one common form. In C, but not C++, a standard compiler can document other return types — and Microsoft has documented void
as a valid return type from VS 2008 onwards.
Because there is no implementation-provided prototype for main()
, the compiler can't officially reject any declarations/definitions of main()
, though it might pass comment on forms it doesn't recognize (GCC does comment on main()
functions that do not return an int
type, for example).
Upvotes: 1