【发布时间】:2015-11-28 01:19:52
【问题描述】:
我正在尝试使用一些针对 Windows 上的 C99 的代码(MSVC、C11)。这是一些用于 OpenCL 调用的调试宏:
#define CL_CHECK(_expr) \
do { \
cl_int _err = _expr; \
if (_err == CL_SUCCESS) \
break; \
fprintf(stderr, "OpenCL Error: '%s' returned %d!\n", #_expr, (int)_err); \
abort(); \
} while (0)
#define CL_CHECK_ERR(_expr) \
({ \
cl_int _err = CL_INVALID_VALUE; \
typeof(_expr) _ret = _expr; \
if (_err != CL_SUCCESS) { \
fprintf(stderr, "OpenCL Error: '%s' returned %d!\n", #_expr, (int)_err); \
abort(); \
} \
_ret; \
})
当 _expr 的返回类型已知为 cl_int 类型时,使用第一个。第二个可以是任何类型,这就是我遇到编译问题的地方。我将 typeof(_expr) 替换为“auto”,但编译器一直在抱怨:
Error 8 IntelliSense: expected an expression d:\work\Labs\dagSimCL\dagSimCL.cpp 136 23 dagSimCL
Error 6 error C2143: syntax error : missing ';' before '{' D:\work\Labs\dagSimCL\dagSimCL.cpp 136 1 dagSimCL
Error 7 error C2143: syntax error : missing ';' before ')' D:\work\Labs\dagSimCL\dagSimCL.cpp 136 1 dagSimCL
Error 5 error C2059: syntax error : '{' D:\work\Labs\dagSimCL\dagSimCL.cpp 136 1 dagSimCL
我向宏扔什么并不重要,它总是一样的。但作为参考,这就是我正在做的事情:
cl_context context = CL_CHECK_ERR(clCreateContext(contextProperties, 1, &devices[device_id], NULL, NULL, &_err));
奇怪的是,当我尝试将代码包装在 do/while 中而不是像第一个宏中的 () 时,它开始抱怨“do”。我在这里有点不知所措。我可以忘记它并跳过错误检查,但我想了解发生了什么问题......
【问题讨论】:
-
你不需要 ; while(0) 之后?
-
通常不会@SnakeSanders。当您使用宏时添加半,例如
CL_CHECK_ERR(expr) ; -
@Snake Sanders:
do/while语句是确保宏扩展为单个语句的技巧。假设;出现在宏调用之后并充当单个语句终止。 -
@JJF:
CL_CHECK(expr);在这种情况下。CL_CHECK_ERR(expr)应该用在表达式上下文中,例如return CL_CHECK_ERR(expr); -
AFAIK,
typeof是 gcc 扩展,“comund statement as an expression”构造也是 gcc 扩展,auto类型说明符是 C++ 特性(它是 C 中的存储类),并且 MSVC 从未符合 C99。
标签: c visual-c++ macros opencl