Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 623069
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T19:03:10+00:00 2026-05-13T19:03:10+00:00

Is it possible to write a C macro that returns the number of its

  • 0

Is it possible to write a C macro that returns the number of its arguments?

I want something that does:

foo(1) -> 1
foo(cat, dog) -> 2
foo(red, green, blue) -> 3

Even better if this macro can be defined in such a way that it works with ## so that

foo(1) -> bar1(1)
foo(cat, dog) -> bar2(cat, dog)
foo(red, green, blue) -> car3(red, green, blue)

Thanks!

EDIT: I really want a macro, not a function. Suggestions to use functions will be downvoted.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T19:03:10+00:00Added an answer on May 13, 2026 at 7:03 pm

    It can be done – the mechanism was explained in the comp.std.c newsgroup in January 2006. There was another question about this recently on SO 2124339.

    I stashed the code away, just in case…

    #ifndef JLSS_ID_NARG_H
    #define JLSS_ID_NARG_H
    
    /*
    ** http://groups.google.com/group/comp.std.c/browse_thread/thread/77ee8c8f92e4a3fb/346fc464319b1ee5?pli=1
    **
    **    Newsgroups: comp.std.c
    **    From: Laurent Deniau <laurent.deniau@cern.ch>
    **    Date: Mon, 16 Jan 2006 18:43:40 +0100
    **    Subject: __VA_NARG__
    **
    **    A year ago, I was asking here for an equivalent of __VA_NARG__ which
    **    would return the number of arguments contained in __VA_ARGS__ before its
    **    expansion. In fact my problem at that time (detecting for a third
    **    argument) was solved by the solution of P. Mensonides. But I was still
    **    thinking that the standard should have provided such a facilities rather
    **    easy to compute for cpp.
    **
    **    This morning I had to face again the same problem, that is knowing the
    **    number of arguments contained in __VA_ARGS__ before its expansion (after
    **    its expansion can always be achieved if you can do it before). I found a
    **    simple non-iterative solution which may be of interest here as an answer
    **    to who will ask in the future for a kind of __VA_NARG__ in the standard
    **    and I post it for archiving. May be some more elegant-efficient solution
    **    exists?
    **
    **    Returns NARG, the number of arguments contained in __VA_ARGS__ before
    **    expansion as far as NARG is >0 and <64 (cpp limits):
    **
    **    #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,[..],_61,_62,_63,N,...) N
    **    #define PP_RSEQ_N() 63,62,61,60,[..],9,8,7,6,5,4,3,2,1,0
    **
    **    [..] stands for the continuation of the sequence omitted here for
    **    lisibility.
    **
    **    PP_NARG(A) -> 1
    **    PP_NARG(A,B) -> 2
    **    PP_NARG(A,B,C) -> 3
    **    PP_NARG(A,B,C,D) -> 4
    **    PP_NARG(A,B,C,D,E) -> 5
    **    PP_NARG(A1,A2,[..],A62,A63) -> 63
    **
    ** ======
    **
    **    Newsgroups: comp.std.c
    **    From: Roland Illig <roland.il...@gmx.de>
    **    Date: Fri, 20 Jan 2006 12:58:41 +0100
    **    Subject: Re: __VA_NARG__
    **
    **    Laurent Deniau wrote:
    **    > This morning I had to face again the same problem, that is knowing the
    **    > number of arguments contained in __VA_ARGS__ before its expansion (after
    **    > its expansion can always be achieved if you can do it before). I found a
    **    > simple non-iterative solution which may be of interest here as an answer
    **    > to who will ask in the future for a kind of __VA_NARG__ in the standard
    **    > and I post it for archiving. May be some more elegant-efficient solution
    **    > exists?
    **
    **    Thanks for this idea. I really like it.
    **
    **    For those that only want to copy and paste it, here is the expanded version:
    **
    ** // Some test cases
    ** PP_NARG(A) -> 1
    ** PP_NARG(A,B) -> 2
    ** PP_NARG(A,B,C) -> 3
    ** PP_NARG(A,B,C,D) -> 4
    ** PP_NARG(A,B,C,D,E) -> 5
    ** PP_NARG(1,2,3,4,5,6,7,8,9,0,    //  1..10
    **         1,2,3,4,5,6,7,8,9,0,    // 11..20
    **         1,2,3,4,5,6,7,8,9,0,    // 21..30
    **         1,2,3,4,5,6,7,8,9,0,    // 31..40
    **         1,2,3,4,5,6,7,8,9,0,    // 41..50
    **         1,2,3,4,5,6,7,8,9,0,    // 51..60
    **         1,2,3) -> 63
    **
    **Note: using PP_NARG() without arguments would violate 6.10.3p4 of ISO C99.
    */
    
    /* The PP_NARG macro returns the number of arguments that have been
    ** passed to it.
    */
    
    #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
    
    #endif /* JLSS_ID_NARG_H */
    

    It works fine as long as there are no more than 64 arguments. Here’s the test code I used:

    #include "narg.h"
    #include <stdio.h>
    
    #define PRINT(pp_narg)     printf("%2d = %s\n", pp_narg, # pp_narg)
    
    #ifndef lint
    /* Prevent over-aggressive optimizers from eliminating ID string */
    extern const char jlss_id_narg_c[];
    const char  jlss_id_narg_c[] = "@(#)$Id: narg.c,v 1.2 2010/01/24 18:12:05 jleffler Exp $";
    #endif  /* lint */
    
    int
    main(void)
    {
        PRINT(PP_NARG(A));
        PRINT(PP_NARG(A, B));
        PRINT(PP_NARG(A, B, C));
        PRINT(PP_NARG(A, B, C, D));
        PRINT(PP_NARG(A, B, C, D, E));
    
        PRINT(PP_NARG(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 1..10
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 11..20
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 21..30
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 31..40
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 41..50
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 51..60
                      1, 2, 3));
    
        /**
        ** If the number of arguments to PP_NARG() is greater than 63, the
        ** 64th argument is returned.  This is well-defined behaviour, but
        ** not exactly what was intended.
        */
        PRINT(PP_NARG(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 1..10
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 11..20
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 21..30
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 31..40
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 41..50
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 51..60
                      1, 2, 3, -123456789));
    
        PRINT(PP_NARG(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 1..10
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 11..20
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 21..30
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 31..40
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 41..50
                      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, // 51..60
                      1, 2, 3, -123456789, -987654321));
    
        return(0);
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Is it possible to write a Macro (using token concatenation) that returns format for
Is it possible to write a macro that has a type and a value
Possible Duplicate: C, Macro defining Macro Does anyone know how to pull off something
I know that it's possible to write a register macro that will map their
Is it possible to write a Common Lisp macro that takes a list of
How do you write a macro with variable number of arguments to define a
Is it possible to write a macro in SQL Server Management Studio that will
Is it possible to write a program that will change the phone numbers a
Is it possible to write a script in Perl that opens different URLs and
Would it be possible to write a script that gave the user the ability

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.