473,804 Members | 3,113 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 12096
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.ne t>
Michael Mair <Mi**********@i nvalid.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_ARG S__))

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.ne t>
Michael Mair <Mi**********@i nvalid.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_ARG S__))

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 (*DebugLogForma t)(char *format,...);
DebugLogFormat debugLogSetup(c har *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,f ormat);
vprintf(format, list);
va_end(list);
}
DebugLogFormat debugLogSetup(c har *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*****@tang o-sierra-oscar-foxtrot-tango.fake.org> wrote:
<snip>
Alternatively,

debug.h
typedef void (*DebugLogForma t)(char *format,...);
DebugLogFormat debugLogSetup(c har *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,f ormat);
vprintf(format, list);
va_end(list);
}
DebugLogFormat debugLogSetup(c har *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(__FIL E__,__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.ne t
Nov 14 '05 #6

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

Similar topics

2
6998
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 delete operator with a macro. I can't replace the delete operator by using void* as the first parameter, because then my code will not be able to modify the calling function's pointer, nor would it get the source file name and line number.
27
5931
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 gcc specific. Is there a way to do it in a standard c++ way? TIA
4
8370
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 all if it's preceded by '#'. Background: I want to produce a string giving the current file and line number in an array of structures, as follows: ---------------
1
6949
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 malloc(int x) as Xmalloc(int x) Now I want to write a macro for Xmalloc which can log the location of the file and the line and the number of bytes allocated.
36
14131
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 (0) \
20
2459
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 instant is implemented. This prompts two questions: 1) Is this an ANSI C feature, or just a compiler-dependent goody? 2) If it is an ANSI C feature, is there anything equivalent for function names, rather than file names?
24
5781
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 macros */ #ifndef PUBLIC #define PUBLIC
10
9847
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
15380
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
9706
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10578
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10321
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10077
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7620
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6853
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5522
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5651
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3820
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.