Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the meaning of the `...` parameter in a C function parameter list [duplicate]

Possible Duplicate:
C/C++: Passing variable number of arguments around

According to the function declaration manner

return-type function-name(parameter-list, ...) {body ...}

Is the following code a kind of overloading?

(in A_FILE.h)

typedef VOID *FUNCTION(UINTN Number, ...);

It seems that I could just pass one Number parameter, or more parameters into the FUNCTION function, so does the number of parameters depends on the function implementation?

like image 979
Charles Avatar asked Dec 27 '12 03:12

Charles


2 Answers

The ellipsis within a function declaration means that it will accept a number of arguments otherwise, variable parameters that are unknown at run-time, which by using the standard header file stdarg.h, the respective functions in that header file 'stdarg.h' can determine what each of the variable parameters are that makes up the argument passing into a function.

Consider this code example:

#define PANIC_BUF_LEN 256
void panic(const char *fmt, ...){
    char buf[PANIC_BUF_LEN];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(errcode);
}

Typical invocation can be one of example:

panic("Error: %s failed! Due to unknown error, message is '%s'\n", "my_function", "Disk not ready");

Will produce an output on console in this manner:

Error: my_function failed! Due to unknown error, message is 'Disk not ready'

Notice the usage of how the functions va_start(...), va_end(...) and not to mention vsprintf(...) will take care of filling in the blanks within the "unknown" parameters provided va_list is initialized to point to the variable parameters which are unknown at run-time.

Edit: Just to emphasize, the invocation assumes that the string parameter in the form of a C string format is less than the maximum size represented by PANIC_BUF_LEN in the above example, nit-picky aside, that is to illustrate how a function can take in a number of standard C formatting strings used, for example, one can specify %d in the string format, and expect a int to match up the parameter.

like image 116
t0mm13b Avatar answered Nov 13 '22 10:11

t0mm13b


It's not overloading in the C++ sense, but it can be used for a similar effect. The ... indicates that the function takes any number of additional arguments after the named arguments (there has to be at least one named argument), and the additional arguments can have any type (sort of).1 The implementation of such a function has to be able to deduce the number and type of its additional arguments at runtime. For instance, printf can print any built-in type, and any number of things at a time, but you have to give it % codes in the format string that correspond to the actual arguments.

One notable example of variable arguments used to simulate C++-style overloading is the open system call, which in C++ terms has two overloads:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

and the manpage is written that way, but if you look in <fcntl.h> you will discover that the actual declaration is

int open(const char *, int, ...);

The implementation only looks at the third argument if the O_CREAT bit is set in the flags, and it's documented that you must provide the third argument if you set that bit. As usual in C, if you do it wrong, the compiler cheerfully watches it blow up on you at runtime.

1 Thanks to a vestigial language feature called "default argument promotion", some numeric types get turned into other, larger numeric types when passed as additional arguments to a function that takes a variable number of arguments. You only have to worry about this if you are writing the body of such a function.

like image 31
zwol Avatar answered Nov 13 '22 08:11

zwol