3

The following code has a different macro expansion for MSVC and GCC compiler:

#include <array>
#include <iostream>

#define UNROLL_REPEAT_I_1(X, ...) X(0, ##__VA_ARGS__)
#define UNROLL_REPEAT_I_2(X, ...)                                              \
  UNROLL_REPEAT_I_1(X, ##__VA_ARGS__) X(1, ##__VA_ARGS__)
#define UNROLL_REPEAT_I_3(X, ...)                                              \
  UNROLL_REPEAT_I_2(X, ##__VA_ARGS__) X(2, ##__VA_ARGS__)

#define BLAS_1V_IT(I, X0, Op0) (X0[I]) Op0

#define BLAS_UNROLL_IT(K, X, ...) X(blas_index + K, ##__VA_ARGS__);

int
main()
{
  double x[10], a;
  int blas_index = 0;
  UNROLL_REPEAT_I_3(BLAS_UNROLL_IT, BLAS_1V_IT, x, = a);

  return 0;
}

For GCC compiler, expansion of UNROLL_REPEAT_I_3 in main function is what I want:

(x[blas_index + 0]) = a; (x[blas_index + 1]) = a; (x[blas_index + 2]) = a;

However, for MSVC compiler, the result is weird and cannot be compiled successfully:

BLAS 1V IT, x, = a(blas index + 0 ); (x, = a[blas index + 1]) ; (x[blas index + 2]) = a;

Is there any feasible modification for this code to make sure it has same expansion by both of the MSVC and GCC compiler?

Xiang Yue
  • 55
  • 3
  • 1
    If you can use use at least C++17 I would ditch the macro and use a function template and a lambda expression. [Here](http://coliru.stacked-crooked.com/a/0066beea571c9077) I use C++20 and a immediately executed lambda (makes the code needed shorter) to run a passed in function N times. Gives you a nice clean syntax of `apply_each_n<3>([&](auto index){ x[blas_index + index] = a; });` in your main function which is very self descriptive. – NathanOliver Nov 12 '22 at 04:13
  • The real question is, does the C++ spec describe the behavior in this instance with enough precision to determine which is right and which is wrong? – Mark Ransom Nov 12 '22 at 05:11
  • 3
    Use `/Zc:preprocessor` :) – Osyotr Nov 12 '22 at 08:29
  • 1
    Duplicate of [this question](https://stackoverflow.com/q/5134523/1983398)? – ssbssa Nov 12 '22 at 12:13
  • `##__VA_ARGS__` is a [gcc-specific non-standard trick](https://stackoverflow.com/questions/52891546/what-does-va-args-mean) – Igor Tandetnik Nov 12 '22 at 17:19
  • @NathanOliver Thanks for your advice, I'd like to use modern C++ template instead of marcos, however I need to make sure the code is compatible with at least C++11. – Xiang Yue Nov 13 '22 at 10:37

0 Answers0