Skip to main content
gamedev.net
🔒 Locked

function(...)

Started by Shai Mar 19, 2005 at 3:54 PM 3 replies 1.1k views
Original Post
Shai
Shai
Tutorial 13 from NeHe uses GLvoid glPrint(const char *fmt, ...) as a function prototype. What exactly does the ... do? At first I thought it just lets you use a variable of a random type, but it seems it's somewhat more complex.
"It's better to regret something you've done than to regret something you haven't done."
load_bitmap_file
load_bitmap_file
It's for functions with variable length parameters. For example, C's printf lets you pass however many parameters you want to it.
Fruny
Fruny
The ellipsis indicates the function can accept a variable number of parameters. Such functions universally rely on the va_start, va_arg and va_end macros (google for details), which essentially let them grab arbitrary blocks of data off the stack (where the function parameters are located). The function relies on its first parameter (here, the format string) to figure out how many parameters are to be read, and what their types are. No checking is done, so if you try to read the wrong number or the wrong types of parameters, all you get is garbage.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Shai
Shai
thnx guys :)
"It's better to regret something you've done than to regret something you haven't done."
MaulingMonkey
MaulingMonkey
As an side:

Many (not all, nor necessairly the majority even - but still many) programmers consider variable length arguments like this to be shoddy programming - no type safety, and the results are undefined if you try to pass a class to the function as one of the variable arguments.

There are alternatives (at least in C++), such as operator chaining. Example from the boost library:

//Replacing printf(...):#include <boost/format.hpp>#include <iostream>using namespace std;using namespace boost;cout << format("%1% %2% %3%") % "I" % "like" % "pie" << endl;//It also works with functions that expect simple strings:#include <string>void function( const string & );function( str( format("%1% %2% %3%") % "I" % "love" % "rootbeer" ) );


Another utility of the boost library that may prove useful:

#include <boost/assign/list_inserter.hpp> // for 'insert()'#include <boost/assert.hpp> #include <string>using namespace std;using namespace boost::assign; // bring 'insert()' into scope {    map<string,int> months;      insert( months )        ( "january",   31 )( "february", 28 )        ( "march",     31 )( "april",    30 )        ( "may",       31 )( "june",     30 )        ( "july",      31 )( "august",   31 )        ( "september", 30 )( "october",  31 )        ( "november",  30 )( "december", 31 );    BOOST_ASSERT( months.size() == 12 );        BOOST_ASSERT( months["january"] == 31 );}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.