473,387 Members | 1,515 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,387 software developers and data experts.

variadic macros

Hi,

is there any way to access individual elements in the body
of a variadic macro? I only found __VA_ARGS__, which always
expands to the complete list.

Thanks for any help,

Christof
Jun 27 '08 #1
8 3393
It would already help if there would be a way to have something
that expands to the number of arguments being passed to the variadic macro.
Christof Warlich schrieb:
Hi,

is there any way to access individual elements in the body
of a variadic macro? I only found __VA_ARGS__, which always
expands to the complete list.

Thanks for any help,

Christof
Jun 27 '08 #2
On 22 May 2008 at 10:29, Christof Warlich wrote:
is there any way to access individual elements in the body
of a variadic macro? I only found __VA_ARGS__, which always
expands to the complete list.
Twelve hours, and not a single language lawyer has come along to explain
that you can't. That's because your question is about C99, and the
luddite regulars in this group won't tolerate any discussion of C
standards more recent than the fall of the Berlin Wall.

Anyway, to answer your question, no there's no way in standard C...
there's not even any way using gcc extensions. I don't know about MS or
lcc extensions - maybe you can with them.

To understand why the answer is no, think about how you'd go about
finding out how many arguments were passed to your variadic function...
now ponder doing that in a macro.

The only purpose of variadic macros is to facilitate providing default
arguments for calls to variadic functions, like the usual
fprintf(stderr, __VA_ARGS__) example.

Jun 27 '08 #3
Christof Warlich <cwarl...@alcatel-lucent.dewrote:
Christof Warlich schrieb:
is there any way to access individual elements in
the body of a variadic macro? I only found
__VA_ARGS__, which always expands to the complete
list.
Not in standard C99.
It would already help if there would be a way to
have something that expands to the number of
arguments being passed to the variadic macro.
There's no shortage on the wish list for standard C.
However that doesn't mean that your actual problem
doesn't have a simple solution.

Perhaps you might like to mention the real problem.
It may be solvable quite easily in standard C.

--
Peter
Jun 27 '08 #4
On May 23, 1:18 am, Peter Nilsson <ai...@acay.com.auwrote:
Christof Warlich <cwarl...@alcatel-lucent.dewrote:
Christof Warlich schrieb:
is there any way to access individual elements in
the body of a variadic macro? I only found
__VA_ARGS__, which always expands to the complete
list.

Not in standard C99.
6.10.3 p 5
The identifier _ _VA_ARGS_ _ shall occur only in the replacement-list
of a function-like macro that uses the ellipsis notation in the parameters..
Jun 27 '08 #5
On May 23, 7:20 pm, vipps...@gmail.com wrote:
On May 23, 1:18 am, Peter Nilsson <ai...@acay.com.auwrote:
Christof Warlich <cwarl...@alcatel-lucent.dewrote:
Christof Warlich schrieb:
is there any way to access individual elements in
the body of a variadic macro? I only found
__VA_ARGS__, which always expands to the complete
list.
Not in standard C99.
6.10.3 p 5
The identifier __VA_ARGS__ shall occur only in the replacement-list
of a function-like macro that uses the ellipsis notation in the parameters.
Whoops; I just realized you meant that accessing individual elements
in the body of a variadic macro is not possible in C99, which is true.
My apologies.
Jun 27 '08 #6
Christof Warlich <cw******@alcatel-lucent.dewrote:
It would already help if there would be a way to have something
that expands to the number of arguments being passed to the variadic macro.
/*
* The PP_NARG macro evaluates to the number of arguments that have been
* passed to it.
*
* Laurent Deniau, "__VA_NARG__," 17 January 2006, <comp.std.c(29 November 2007).
*/
#define PP_NARG(...) PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__)

#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N

#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0

Jun 27 '08 #7
Christof Warlich <cw******@alcatel-lucent.dewrote:
Hi,
is there any way to access individual elements in the body
of a variadic macro? I only found __VA_ARGS__, which always
expands to the complete list.
So, using Laurent's solution you can do lots of interesting things. For
instance, you can overload functions or macros:

#define foreach2(p, a) \
for (typeof(&(a)[0]) p = (a); p - (a) < lengthof(a); p++)

#define foreach3(p, a, n) \
for (typeof(&(a)[0]) p = (a); p - (a) < (n); p++)

#define foreach_(N, ...) PASTE(foreach, N)(__VA_ARGS__)
#define foreach(...) foreach_(PP_NARG(__VA_ARGS__), __VA_ARGS__)

That technique has proven very useful. Another interesting trick is to peek
into __VA_ARGS__. That requires some indirection, and extending calls with
dummy arguments. Here's something along those lines which I wrote this past
weekend; very simple. The '3' is the default value, which can be overridden
by the caller merely providing a second argument, shifting the default
argument into the ether. (Visual Studio doesn't support much of C99, but
2005 supports __VA_ARGS__; but don't quote me, because I almost always use
Mingw).

/*
* Prefetching
*/
#if __GNUC__ >= 3
#define prefetch_((w), (p), (l), ...) __builtin_prefetch((p), (w), (l))
#define prefetch(...) prefetch_(0, __VA_ARGS__, 3)
#define prefetchw(...) prefetch_(1, __VA_ARGS__, 3)
#elif _MSC_VER >= 1400
#include <winnt.h>
#define prefetch_((p), (l), ...) PreFetchCacheLine((l), (p))
#define prefetch(...) prefetch_(__VA_ARGS__, 3)
#define prefetchw(...) prefetch_(__VA_ARGS__, 3)
#else
#define prefetch(...)
#define prefetchw(...)
#endif
Following below is one of my attempts to combine that with PP_NARG to get
something more generic and reuseable. The result is PP_MAP, which is at the
end. I've used it to prefix arguments in a DNS library, so callers can do
things like

dns_lookup(dnsctx, a, aaaa, mx)

which using

#define dns_rr_prefix(type) dns_rr_##type
#define dns_lookup(dnsctx, ...) \
dns_lookup((dnsctx), PP_NARG(__VA_ARGS__), (int[]) { \
PP_MAP(dns_rr_prefix, __VA_ARGS__) \
})

gets turned into

dns_lookup(dnsctx, 3, (int[]){ dns_rr_a, dns_rr_aaaa, dns_rr_mx })

Actually, I do something a little different by using static inline
functions, so I can turn types into a 64-bit unsigned integral bitmap w/
overflow (types 62) copied into a compound literal variable-length array.
GCC -O2 can turn all of that into constants. Probably overkill for a DNS
library, but at the very least it improves the semantics of the user API
(and I always like to play around w/ loop elimination strategies).

The semantics of PP_MAP leaves something to be desired. It's more an
experiment. Laurent's PP_NARG, on the other hand, is close to perfection as
far as reusable macros go.
/*
* Select leading N items from list.
*/
#define PP_ARGV(N, ...) PASTE(PP_ARGV, N)(__VA_ARGS__)
#define PP_ARGV1(_00,...) \
_00
#define PP_ARGV2(_00,_01,...) \
_00,_01
#define PP_ARGV3(_00,_01,_02,...) \
_00,_01,_02
#define PP_ARGV4(_00,_01,_02,_03,...) \
_00,_01,_02,_03
#define PP_ARGV5(_00,_01,_02,_03,_04,...) \
_00,_01,_02,_03,_04
#define PP_ARGV6(_00,_01,_02,_03,_04,_05,...) \
_00,_01,_02,_03,_04,_05
#define PP_ARGV7(_00,_01,_02,_03,_04,_05,_06,...) \
_00,_01,_02,_03,_04,_05,_06
#define PP_ARGV8(_00,_01,_02,_03,_04,_05,_06,_07,...) \
_00,_01,_02,_03,_04,_05,_06,_07
#define PP_ARGV9(_00,_01,_02,_03,_04,_05,_06,_07,_08,...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08
#define PP_ARGV10(_00,_01,_02,_03,_04,_05,_06,_07,_08,_09, ...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08,_09
#define PP_ARGV11(_00,_01,_02,_03,_04,_05,_06,_07,_08,_09, _0a,...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08,_09,_0a
#define PP_ARGV12(_00,_01,_02,_03,_04,_05,_06,_07,_08,_09, _0a,_0b,...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08,_09,_0a,_0b
#define PP_ARGV13(_00,_01,_02,_03,_04,_05,_06,_07,_08,_09, _0a,_0b,_0c,...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08,_09,_0a,_0b,_0 c
#define PP_ARGV14(_00,_01,_02,_03,_04,_05,_06,_07,_08,_09, _0a,_0b,_0c,_0d,...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08,_09,_0a,_0b,_0 c,_0d
#define PP_ARGV15(_00,_01,_02,_03,_04,_05,_06,_07,_08,_09, _0a,_0b,_0c,_0d,_0e,...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08,_09,_0a,_0b,_0 c,_0d,_0e
#define PP_ARGV16(_00,_01,_02,_03,_04,_05,_06,_07,_08,_09, _0a,_0b,_0c,_0d,_0e,_0f,...) \
_00,_01,_02,_03,_04,_05,_06,_07,_08,_09,_0a,_0b,_0 c,_0d,_0e,_0f
/*
* Apply function-like macro F to each item in argument list.
*/
#define PP_MAP16(F,_00,_01,_02,_03,_04,_05,_06,_07,_08,_09 ,_0a,_0b,_0c,_0d,_0e,_0f,...) \
F(_00),F(_01),F(_02),F(_03),F(_04),F(_05),F(_06),F (_07), \
F(_08),F(_09),F(_0a),F(_0b),F(_0c),F(_0d),F(_0e),F (_0f)

#define PP_MAP_(F,...) PP_MAP16(F,__VA_ARGS__)
#define PP_MAP(F,...) PP_ARGV(PP_NARG(__VA_ARGS__),PP_MAP_(F,__VA_ARGS__ ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0))
Jun 27 '08 #8
William Ahern <wi*****@wilbur.25thandclement.comwrote:
Christof Warlich <cw******@alcatel-lucent.dewrote:
Hi,
is there any way to access individual elements in the body
of a variadic macro? I only found __VA_ARGS__, which always
expands to the complete list.
So, using Laurent's solution you can do lots of interesting things. For
instance, you can overload functions or macros:
#define foreach2(p, a) \
for (typeof(&(a)[0]) p = (a); p - (a) < lengthof(a); p++)
#define foreach3(p, a, n) \
for (typeof(&(a)[0]) p = (a); p - (a) < (n); p++)
Oops. A poor example because `typeof' is an extension, but it remains
illustrative of C99 standard compliant overloading using number of arguments
as the differentiator.

Jun 27 '08 #9

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

Similar topics

1
by: jois.de.vivre | last post by:
Hi, I'm writing a C++ program that uses C style macros for debugging purposes. I have code that looks something like this: #define DEBUG(str, ...) Show(__FILE__, __LINE__, str, ##...
3
by: Trent Buck | last post by:
(Note: C99 supports variadic macros, but C89 does not.) I'm pretty sure what I'm trying to do is impossible, but I'll ask here in case I'm missing something. I'm trying to define generic,...
19
by: Ross A. Finlayson | last post by:
Hi, I hope you can help me understand the varargs facility. Say I am programming in ISO C including stdarg.h and I declare a function as so: void log_printf(const char* logfilename, const...
7
by: Michael B Allen | last post by:
If I define a variadic macro like say: #define PRINT(fmt, ...) _myprintf(__FILE__ ": " fmt, __VA_ARGS__) and I call this like: PRINT("no args"); the preprocessor generates:
3
by: Thomas Carter | last post by:
I understand that C99 supports variadic macros. However, is it not the case that a variadic macro defined as #define SAMPLE_MACRO(...) Bloody-blah must take at least one argument? I would be...
15
by: Urs Thuermann | last post by:
I want to write a macro that produces debug output and has a variable number of arguments, so that I can use like this: int i; char *s; DBG("simple message\n"); DBG("message with an int...
14
by: jontwang | last post by:
How do you get a count of the number of arguments passed into a variadic macro?
12
by: Laurent Deniau | last post by:
I was playing a bit with the preprocessor of gcc (4.1.1). The following macros expand to: #define A(...) __VA_ARGS__ #define B(x,...) __VA_ARGS__ A() -nothing, *no warning* A(x) -x ...
9
by: CryptiqueGuy | last post by:
Consider the variadic function with the following prototype: int foo(int num,...); Here 'num' specifies the number of arguments, and assume that all the arguments that should be passed to this...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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:
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...

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.