473,394 Members | 2,160 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Macro Variable Argument List with __FILE__ and __LINE__

I couldn't find an example of this anywhere so I post it in the hope
that someone finds it useful. I believe this is compiler specific (I'm
using gcc), as C99 defines __VA_ARGS__. Comments are welcome.

This will print the file name and line number followed by a format
string and a variable number of arguments. The key here is that you
MUST have a space between __LINE__ and the last comma, otherwise
__LINE__ gets eaten by the ## if args is empty. It took me awhile to
figure that out.

#define DEBUGLOG(fmt, args...) printf("%s(%d)"fmt , __FILE__ ,
__LINE__ , ## args)

I'm curious, does anyone know if the equivelant can be done using
__VA_ARGS__?

Nov 14 '05 #1
5 12068
jake1138 wrote:
I couldn't find an example of this anywhere so I post it in the hope
that someone finds it useful. I believe this is compiler specific (I'm
using gcc), as C99 defines __VA_ARGS__. Comments are welcome.

This will print the file name and line number followed by a format
string and a variable number of arguments. The key here is that you
MUST have a space between __LINE__ and the last comma, otherwise
__LINE__ gets eaten by the ## if args is empty. It took me awhile to
figure that out.

#define DEBUGLOG(fmt, args...) printf("%s(%d)"fmt , __FILE__ ,
__LINE__ , ## args)

I'm curious, does anyone know if the equivelant can be done using
__VA_ARGS__?


I do.
Probably you want to know whether it can be done: Yes, it can be done.

If you want to know how:
#define DEBUGLOG(fmt, ...) \
printf("%s(%d)"fmt, __FILE__, __LINE__, __VA_ARGS__)

(untested)
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #2
>jake1138 wrote:
This [gcc-specific trick] will print the file name and line number
followed by a format string and a variable number of arguments. ...
[formatting broken originally by google, now fixed:]
#define DEBUGLOG(fmt, args...) \
printf("%s(%d)"fmt , __FILE__ , __LINE__ , ## args)

I'm curious, does anyone know if the equivelant can be done using
__VA_ARGS__?

In article <36*************@individual.net>
Michael Mair <Mi**********@invalid.invalid> wrote:I do.
Probably you want to know whether it can be done: Yes, it can be done.

If you want to know how:
#define DEBUGLOG(fmt, ...) \
printf("%s(%d)"fmt, __FILE__, __LINE__, __VA_ARGS__)

(untested)


This is not quite equivalent. GCC's special "prefix ##" syntax
means "remove the preceding pp-token if the variable arguments
are missing". Hence, if one writes:

DEBUGLOG("got here\n");

with the gcc version, one gets:

printf("%s(%d)""got here", __FILE__, __LINE);

but the C99 version produces:

printf("%s(%d)""got here", __FILE__, __LINE,);

which is not syntactically valid.

There appears to be no way to achieve the desired effect in C99.
As a workaround, one can write:

#define DEBUGLOG(...) \
(printf("%s(%d)", __FILE__, __LINE), printf(__VA_ARGS__))

In other words, just use two calls. Or instead of calling printf()
directly, call your own function that takes three-or-more arguments:

extern int debuglog(const char *, int, const char *, ...);
#define DEBUGLOG(...) debuglog(__FILE__, __LINE__, __VA_ARGS__)

In either case, __VA_ARGS__ will necessarily expand to at least one
parameter, so that the "remove preceding pp-token" behavior is never
needed.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #3
Chris Torek wrote:
jake1138 wrote:
This [gcc-specific trick] will print the file name and line number
followed by a format string and a variable number of arguments. ...

[formatting broken originally by google, now fixed:]

#define DEBUGLOG(fmt, args...) \
printf("%s(%d)"fmt , __FILE__ , __LINE__ , ## args)

I'm curious, does anyone know if the equivelant can be done using
__VA_ARGS__?

In article <36*************@individual.net>
Michael Mair <Mi**********@invalid.invalid> wrote:
I do.
Probably you want to know whether it can be done: Yes, it can be done.

If you want to know how:
#define DEBUGLOG(fmt, ...) \
printf("%s(%d)"fmt, __FILE__, __LINE__, __VA_ARGS__)

(untested)

This is not quite equivalent. GCC's special "prefix ##" syntax
means "remove the preceding pp-token if the variable arguments
are missing". Hence, if one writes:

DEBUGLOG("got here\n");

with the gcc version, one gets:

printf("%s(%d)""got here", __FILE__, __LINE);

but the C99 version produces:

printf("%s(%d)""got here", __FILE__, __LINE,);

which is not syntactically valid.

There appears to be no way to achieve the desired effect in C99.
As a workaround, one can write:

#define DEBUGLOG(...) \
(printf("%s(%d)", __FILE__, __LINE), printf(__VA_ARGS__))

In other words, just use two calls. Or instead of calling printf()
directly, call your own function that takes three-or-more arguments:

extern int debuglog(const char *, int, const char *, ...);
#define DEBUGLOG(...) debuglog(__FILE__, __LINE__, __VA_ARGS__)

In either case, __VA_ARGS__ will necessarily expand to at least one
parameter, so that the "remove preceding pp-token" behavior is never
needed.


Thank you very much!
I never used this gcc extension (-std=cXX -pedantic...), so I was
too quick with my assumptions.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #4
"jake1138" <co******@gmail.com> wrote:
# I couldn't find an example of this anywhere so I post it in the hope
# that someone finds it useful. I believe this is compiler specific (I'm
# using gcc), as C99 defines __VA_ARGS__. Comments are welcome.
#
# This will print the file name and line number followed by a format
# string and a variable number of arguments. The key here is that you
# MUST have a space between __LINE__ and the last comma, otherwise
# __LINE__ gets eaten by the ## if args is empty. It took me awhile to
# figure that out.
#
# #define DEBUGLOG(fmt, args...) printf("%s(%d)"fmt , __FILE__ ,
# __LINE__ , ## args)

Alternatively,

debug.h
typedef void (*DebugLogFormat)(char *format,...);
DebugLogFormat debugLogSetup(char *file,int line);
#define DEBUGLOG (debugLogSetup(__FILE__,__LINE__))
debug.c
static char *file; static int line;
static void debugLogFormat(char *format,...) {
printf("[%s:%d] ",file,line);
va_list list; va_start(list,format);
vprintf(format,list);
va_end(list);
}
DebugLogFormat debugLogSetup(char *file0,int line0) {
file = file0; line = line0;
return debugLogFormat;
}

--
SM Ryan http://www.rawbw.com/~wyrmwif/
A bunch of savages in this town.
Nov 14 '05 #5
On Mon, 07 Feb 2005 12:05:08 -0000, SM Ryan
<wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
<snip>
Alternatively,

debug.h
typedef void (*DebugLogFormat)(char *format,...);
DebugLogFormat debugLogSetup(char *file,int line);
#define DEBUGLOG (debugLogSetup(__FILE__,__LINE__))
debug.c
static char *file; static int line;
static void debugLogFormat(char *format,...) {
printf("[%s:%d] ",file,line);
va_list list; va_start(list,format);
vprintf(format,list);
va_end(list);
}
DebugLogFormat debugLogSetup(char *file0,int line0) {
file = file0; line = line0;
return debugLogFormat;
}


Not safe for threading, which is not in standard C but is in many C
systems and programs. Why not just

..h
typedef int like_printf (const char * /*restrict*/, ...);
like_printf * logPrefix (const char * file, /*unsigned?*/long line);
#define DEBUGLOG logPrefix(__FILE__,__LINE__) /*printfargs*/
..c
like_printf * logPrefix (const char * file, long line)
{ printf ("[%s:%ld] ", file, line); return printf; }
or even
static bool logflag = false;
/* some way to set to true -- or viceversa */
static int dont_printf (const char * /*restrict*/ fmt, ...)
{ return 0; }
like_printf * logPrefix (const char * file, /*ditto*/long line)
{ if( !logflag ) return dont_printf;
/*else*/ /*as before*/ }

Note that this evaluates the log-data arguments even if logging is
disabled by the flag; dont_printf is actually called but discards the
values. This may be costly and generally it is bad style to have
needed sideeffects in statements whose apparent purpose is debugging;
OTOH macro schemes that suppress the evaluation need to be tested in
(only?) the release version, or code-reviewed carefully, or both, to
ensure that they don't have such bugs.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: foo | last post by:
I'm creating a debug class called debug_mem_allocation for the purpose of finding memory leaks. I used macro's to replace the new and delete operators. My problem is with trying to replace the...
27
by: TheDD | last post by:
Hello all, right now, i'm using the following macro to automatically add informations to exceptions: #define THROW(Class, args...) throw Class(__FILE__, __LINE__, ## args) but AFAIK, it's...
4
by: Dom Gilligan | last post by:
Is there any way to get the preprocessor to produce the current line number in double quotes? At first sight, gcc seems to replace __LINE__ last (which would make sense), and so won't replace it at...
1
by: Spry | last post by:
Hi, I wanted to write macros for finding the number of memory allocations and deallocations also wanted to find the locations. The code I have is a pretty big one. I have a wrapper on top of...
36
by: Martin | last post by:
Can anyone help with a quick query... I've seen the ASSERT macro defined as: #define ASSERT(f) \ do { \ if (!(f) && assertFailedOnLine (THIS_FILE, __LINE__)) \ FatalExit (0); \ } while...
20
by: Jim Ford | last post by:
I understand that some compilers define a symbol that can be used anywhere in the code in order to find out, at run time, the name of the file where the code corresponding to the current execution...
24
by: Robin Cole | last post by:
I'd like a code review if anyone has the time. The code implements a basic skip list library for generic use. I use the following header for debug macros: /* public.h - Public declarations and...
10
by: Praveen.Kumar.SP | last post by:
Hi Could anyone solve the problem for the code below The Code: #include "stdio.h" #include "iostream.h" void Temp( int a, char* str,...)
33
by: Peng Yu | last post by:
Hi, __PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm wondering if there is a macro to get the class name inside a member function. Thanks, Peng
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.