I saw someone's C++ code has function declaration like below:
void information_log( const char* fmt , ...)
or catch block like
catch(...)
{
}
What does "..." mean?
I saw someone's C++ code has function declaration like below:
void information_log( const char* fmt , ...)
or catch block like
catch(...)
{
}
What does "..." mean?
The ellipsis notation represents variable parameter list.
http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html
http://msdn.microsoft.com/en-us/library/fxhdxye9(VS.80).aspx
Please see Functions with an Unspecified Number of Parameters
Using the ellipsis, ..., with C++ function prototypes, means that the function can be specified with an unknown number and type of parameters. This feature can be used to suppress parameter type checking and to allow flexibility in the interface to the function. C++ allows functions be to declared with an unspecified number of arguments.
For a catch, it means catch anything. So all exceptions thrown will enter this catch block.
For an argument list, it means a variable number of arguments will be there. You have to use the stdarg.h API to parse them.
Those are really two separate questions here, just using the same symbol. :-)
The prototype simply indicates a variable number of arguments. All I can really say is that it's a bit like C's printf
function, if you happen to know that. The function just keeps pulling in arguments as it needs them.
The catch (...)
code simply means, catch any exception. (Usually you put this after a number of specific catch blocks, so that this works as a "catch-all".)
$5.2.2/6 - "A function can be declared to accept fewer arguments (by declaring default arguments (8.3.6)) or more arguments (by using the ellipsis, ... 8.3.5) than the number of parameters in the function definition (8.4). [Note: this implies that, except where the ellipsis (...) is used, a parameter is available for each argument.]"
That pretty well sums up the interepretation of the declaration of "information_log" in OP
$15.3/6 - "A ... in a handler’s exception-declaration functions similarly to ... in a function parameter declaration; it specifies a match for any exception. If present, a ... handler shall be the last handler for its try block."
Though not a standard term, it is frequently referred to as the catch all clause or catch all handler.
void f(){
try{
throw 2.2; // throw double
}
catch(int){} // standard conversion from double to int not permitted
catch(...){
cout << "catch it here"; // is caught here in catch all clause
}
}
int main(){
f();
}
The ellipsis ...
, in a function prototype, is used to denote the function as variadic. That is, it enables a variable number of arguments to be passed into the function. In this form, a function must define some way for the user to specify exactly how many arguments they presented, since the variadic library functions in C++ can't determine this information dynamically.
For example, the stdio function printf
is one such function with the prototype:
int printf(const char *format, ...);
Presumably, from the similarities between the two prototypes, the information_log
function you describe is designed to mirror much of printf
's functionality and perhaps even internally uses printf
, or one of its cousins.
The following is an example of how to implement a variadic function:
// cstdarg provides access to the arguments passed to the ellipsis
#include <cstdarg> // or (#include <stdarg.h>)
#include <cstdio>
#include <cstring>
// Concatenates as many strings as are present
void concatenate(char ** out, int num_str, ...)
{
// Store where the arguments are in memory
va_list args;
// Find the first variadic argument, relative to the last named argument
va_start(args, num_str);
int out_len = 0;
int * lengths = new int[num_str];
char ** strings = new char*[num_str];
// Extract the strings from the variadic argument list
for(int i = 0; i < num_str; i++)
{
// Specify the position in the argument list and the type
// Note: You must know the type, stdarg can't detect it for you
strings[i] = va_arg(args, char *);
lengths[i] = strlen(strings[i]);
out_len += lengths[i];
}
// Concatenate the strings
int dest_cursor = 0;
(*out) = new char[out_len + 1];
for(int i = 0; i < num_str; i++)
{
strncpy( (*out) + dest_cursor, strings[i], lengths[i]);
dest_cursor += lengths[i];
}
(*out)[dest_cursor] = '\0';
// Clean up
delete [] strings;
delete [] lengths;
va_end(args);
}
int main()
{
char * output = NULL;
// Call our function and print the result
concatenate(&output, 5, "The ", "quick", " brown ", "fox ", "jumps!\n");
printf("%s", output);
delete [] output;
return 0;
}