Stringified __LINE__

M

Michael B Allen

How does the following work and is it portable?

/*
this uses a little trick to allow __LINE__ to be stringified
*/
#define _STRING_LINE_(s) #s
#define _STRING_LINE2_(s) _STRING_LINE_(s)
#define __LINESTR__ _STRING_LINE2_(__LINE__)
#define __location__ __FILE__ ":" __LINESTR__

Result:

printf("%s", __location__);

becomes:

printf("%s", "t0.c" ":" "27");

and prints:

t0.c:27

Mike

PS: macros found in talloc.h at junkcode.samba.org
 
S

Serve Lau

Michael B Allen said:
How does the following work and is it portable?

/*
this uses a little trick to allow __LINE__ to be stringified
*/
#define _STRING_LINE_(s) #s
#define _STRING_LINE2_(s) _STRING_LINE_(s)
#define __LINESTR__ _STRING_LINE2_(__LINE__)
#define __location__ __FILE__ ":" __LINESTR__

__location__ expands to "bla.c" ":" __LINESTR__
__LINESTR__ expands to _STRING_LINE2_(42)
_STRING_LINE2 expands to "42"

so you have "bla.c" ":" "42" which you can view as "bla.c:42"

In C you can append string literals like this at compile time.

One tip. Dont use names which start with underscores
 
W

Walter Roberson

:How does the following work and is it portable?

:/*
: this uses a little trick to allow __LINE__ to be stringified
:*/
:#define _STRING_LINE_(s) #s
:#define _STRING_LINE2_(s) _STRING_LINE_(s)
:#define __LINESTR__ _STRING_LINE2_(__LINE__)

Portable from C89 onward.

The way it work has to do with the details of #, which is magic in
that it only does one level of argument substituation instead of continuing
onward until there are not more substituations available.

The call to _STRING_LINE2_ is not in itself a use of #, so the
parameter, __LINE__, will have its value substituted before _STRING_LINE
is called. _STRING_LINE_ then does one level of substitution, stringifying
the first level value of the dummy parameter, s, and thus stringifying
the line number.

If you were to call _STRING_LINE_(__LINE__) directly then because
_STRING_LINE only does one level of substitution, it would substitute
the literal string __LINE__ in and would stringify that, producing
"__LINE__" rather than the quoted equivilent of the line number.

The ## preprocessor operator has the same kind of magic, so you have to
go through similar levels of indirection for it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top