将CUDA内核调用作为参数宏传递时,预处理器宏中的参数数不正确

将CUDA内核调用作为参数宏传递时,预处理器宏中的参数数不正确,cuda,macros,c-preprocessor,preprocessor,nvcc,Cuda,Macros,C Preprocessor,Preprocessor,Nvcc,我有以下宏 #define TIMEIT( variable, body ) \ variable = omp_get_wtime(); \ body; \ variable = omp_get_wtime() - variable; 我使用它非常简单地为代码的各个部分计时。 但是,宏调用对逗号很敏感,使用三重V形语法的CUDA内核调用会导致预处理器认为宏传递了2个以上的参数 有办法解决这个问题吗?因为C99/C++11,您可以使用可变参数varargs宏来解决这个问题。您可以使用。。。作为最

我有以下宏

#define TIMEIT( variable, body ) \
variable = omp_get_wtime(); \
body; \
variable = omp_get_wtime() - variable;
我使用它非常简单地为代码的各个部分计时。 但是,宏调用对逗号很敏感,使用三重V形语法的CUDA内核调用会导致预处理器认为宏传递了2个以上的参数


有办法解决这个问题吗?

因为C99/C++11,您可以使用可变参数varargs宏来解决这个问题。您可以使用。。。作为最后一个参数;在宏的主体中,_VA_ARGS_uuu将替换为宏调用的尾随参数,逗号保持不变:

#define TIMEIT( variable, ... )   \
    variable = omp_get_wtime();   \
    __VA_ARGS__;                  \
    variable = omp_get_wtime() - variable;
对于不支持varargs宏的编译器,唯一的替代方法是尝试通过仅在括号表达式中使用逗号来保护所有逗号。由于括号保护逗号不被视为宏参数分隔符,因此许多逗号自然是安全的。但是有很多例外,例如C++模板参数列表不保护逗号,声明多个对象,并且-正如你所说的——三个雪佛龙调用。其中一些可能比其他更难保护

特别是,例如,我不知道是否可以在CUDA内核调用周围加上多余的括号。当然,如果nvcc确实处理varargs宏,则不需要这样做。但基于此,我不太确定。nvcc基于EDG compilet,这是一致的,但nvidia似乎没有记录使用的标准版本