2

Kindly let me know If there is way where I could use variable arguments inside a macro function and make the below macro code working.

To put it other way, Is there any way where I could use local variables in va_start.

typedef struct { char *p1; char *p2; char *p3; }Pointers; #define NULLCHECK_VR(num, ...) \ { \ va_list valist; \ int v_index; \ \ va_start(valist, num); \ \ for( v_index=0; v_index < num; v_index++) \ { \ if( NULL == va_arg(valist, void *)) \ { \ printf("NULL \n"); \ } \ else \ { \ printf("NOT NULL \n"); \ } \ } \ \ va_end(valist); \ } int main(void) { Pointers ptr; memset(&ptr, 0, sizeof(Pointers)); NULLCHECK_VR(3, ptr.p1, ptr.p2, ptr.p3) return (0); } 
4
  • 7
    C or C++? C++ has variadic template to resolve your issue. Commented Jan 14, 2020 at 10:09
  • 1
    MACRO is not function (but text replacement). so va_start(valist, num); is wrong as it applies to .. main. Commented Jan 14, 2020 at 10:10
  • You're mixing C-style variadic functions with variadic macros when you could be using a variadic template (if you're using C++ which I'm not sure you are). Commented Jan 14, 2020 at 10:11
  • Remove the #define and you will be fine Commented Jan 14, 2020 at 10:15

2 Answers 2

6

You might use regular function:

void NULLCHECK_VR(int num, ...) { va_list valist; int v_index; va_start(valist, num); for( v_index=0; v_index < num; v_index++) { if( NULL == va_arg(valist, void *)) { printf("NULL\n"); } else { printf("NOT NULL\n"); } } va_end(valist); } 

or in C++ (17)

template <typename Ts> void NULLCHECK_VR(const Ts*... ptrs) { ((std::cout << (ptrs == nullptr ? "NULL\n" : "NOT NULL\n")), ...); } 
Sign up to request clarification or add additional context in comments.

Comments

2

You cannot use a va_list to access local variables. The va_start, va_copy and va_end macros are only for handling variadic function arguments. A macro is not a function.

For C variadic macros, the __VA_ARGS__ identifier in the macro replacement text will expand to the variadic arguments, so a possible implementation of your NULLCHECK_VR macro is as follows:

#define NULLCHECK_VR(num, ...) \ do { \ void *_ptrs[] = { __VA_ARGS__ }; \ int _num = (num); \ int v_index; \ \ for (v_index = 0; v_index < _num; v_index++) \ { \ if (NULL == _ptrs[v_index]) \ { \ printf("NULL \n"); \ } \ else \ { \ printf("NOT NULL \n"); \ } \ } \ } while (0) 

Here, __VA_ARGS__ has been used to initialize the local _ptrs array.

(I added local variable _num to avoid expanding the num parameter multiple times, and I used the do while (0) idiom to turn the block into a statement.)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.