How to use C89 with certain C99 features
Steffen Dettmer
steffen.dettmer@googlemail.com
Tue Apr 5 15:17:00 GMT 2011
* On Tue, Apr 5, 2011 at 4:02 PM, <richardcavell@mail.com> wrote:
> That's what I'm thinking. I can't figure out how to provide the
> functionality I need using C89. The functionality I need is:
>
> 1. Variadic macros, which allows me to do this:
>
> #define myprintfwrapper (A,...) myfunc (__FILE__,__LINE__,A,__VA_ARGS__)
> void myfunc (char *szfile, int line, A, ...);
We have such situations where the platforms w/o vaargs are
"small" anyway and the overhead for __FILE__ in the binaries is
bad anyway, so simple solution is to simply on those platforms do
/not/ use file and line; two implementations of myfunc: one with
file and line (f_l), other without, called by "double-brace-macros".
Here an example.
#if HAVE_VAARGS
#define myprintf(args) myTemp args
#define myTemp(fmt, args...) myprintfunc_f_l(__FILE__, __LINE__, fmt, ## args)
int myprintfunc_f_l(const char *file, int line, const char *fmt, ...);
#else /* no HAVE_VAARGS */
#define myprintf(args) myprintfunc args
int myprintfunc(const char *fmt, ...);
#endif /* no HAVE_VAARGS */
you'd use the macro with double braces:
int func(void)
{
mypriuntf(("Hello, %s\n!", world));
}
of course for main development and debugging it is suited to use
a platform with vaargs, but the other platforms at least do work
(just do not print __FILE__ and __LINE__, but the message).
If you have a platform without elipsis and very limited resources
you could even redefine __FILE__ to a "file counter" (short
number for each file or use MYFILENUMBER) and log only __FILE__
and __LINE__ which for error logging sometimes is a small bit
better than nothing.
> 2. Struct initialization with run-time data, which allows
> const members of the struct to contain run-time data. I make
> the members const for efficiency and error prevention.
> If anyone can figure out how to do those things with C89, let me know.
when having e.g.:
function func(long seconds)
{
struct timeval t = { seconds, 0 };
}
you should to use
function func(long seconds)
{
struct timeval t = { 0 };
t.tv_sec = seconds;
}
oki,
Steffen
More information about the Gcc-help
mailing list