C将函数调用作为参数检查宏定义时出错赢得';在MSVC上编译
我正在尝试使用一些针对Windows上C99的代码(MSVC,C11)。这是一些用于OpenCL调用的调试宏:C将函数调用作为参数检查宏定义时出错赢得';在MSVC上编译,c,visual-c++,macros,opencl,C,Visual C++,Macros,Opencl,我正在尝试使用一些针对Windows上C99的代码(MSVC,C11)。这是一些用于OpenCL调用的调试宏: #define CL_CHECK(_expr) \ do { \ cl_int _err = _expr;
#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”。我在这里有点不知所措。我可以忘记它,跳过错误检查,但我想了解出了什么问题……CL\u CHECK\u EXPR()
宏对我来说似乎不正确:
- 对
的测试应始终失败,因为\u err
应不同于CL\u无效值
CL\u成功
- 我认为
应该是从\u err
派生出来的,但在编写时,它不起作用\u expr
- 针对
缺乏可移植性的一个简单修复方法是将实际类型作为宏参数传递。在C.typeof
中不支持C++中的“<代码>自动< /COD>关键字”类型的支持
- 此外,您的编译器可能不支持表达式语句扩展,这使得您几乎没有其他选择
CL\u CHECK\u EXPR()
宏似乎不正确:
- 对
的测试应始终失败,因为\u err
应不同于CL\u无效值
CL\u成功
- 我认为
应该是从\u err
派生出来的,但在编写时,它不起作用\u expr
- 针对
缺乏可移植性的一个简单修复方法是将实际类型作为宏参数传递。在C.typeof
中不支持C++中的“<代码>自动< /COD>关键字”类型的支持
- 此外,您的编译器可能不支持表达式语句扩展,这使得您几乎没有其他选择
cl_context context = CL_CHECK_EXPR(...);
C中的表达式不能包含复合语句(即{}
)或if
语句或声明语句等语句
您确实需要将这些内容放入一个返回所需表达式的函数中,并让CL\u CHECK\u EXPR()
宏调用该函数。CL\u CHECK\u EXPR()
既不是有效的C表达式,也不是用于赋值运算符右侧的初始值设定项列表:
cl_context context = CL_CHECK_EXPR(...);
C中的表达式不能包含复合语句(即{}
)或if
语句或声明语句等语句
您确实需要将这些内容放入一个返回所需表达式的函数中,并让
CL\u CHECK\u EXPR()
宏调用该函数;在while(0)之后?通常不在蛇食者。当您使用宏时会添加semi,例如CL\u CHECK\u ERR(expr)
@Snake Sanders:do/while语句是确保宏扩展为单个语句的技巧。“代码>假定在宏调用后立即出现,并充当单语句终止。@JJF:CL\u CHECK(expr)代码>在这种情况下CL\u CHECK\u ERR(expr)
应该在表达式上下文中使用,例如return CL\u CHECK\u ERR(expr)代码> AFAIK,<代码> Type of /Cuth>是GCC扩展,“COMPUND语句作为表达式”构造也是GCC扩展,自动< /Cord>类型说明符是C++特性(C是存储类),MSVC从来没有符合C99。在while(0)之后?通常不在蛇食者。当您使用宏时会添加semi,例如CL\u CHECK\u ERR(expr)
@Snake Sanders:do/while
语句是确保宏扩展为单个语句的技巧。“代码>假定在宏调用后立即出现,并充当单语句终止。@JJF:CL\u CHECK(expr)代码>在这种情况下CL\u CHECK\u ERR(expr)
应该在表达式上下文中使用,例如return CL\u CHECK\u ERR(expr)代码> AFAIK,<代码> Type of /Cuth>是GCC扩展,“COMPUND语句作为表达式”构造也是GCC扩展,自动< /Cord>类型说明符是C++特性(C是存储类),MSVC从来没有符合C99。<代码> {Err> <代码>由“<代码>请看问题中的最后一段代码。我明白了,这是一个非常丑陋的副作用。您肯定应该将状态返回变量的名称作为宏参数传递。如果是C++11,恐怕将表达式类型作为额外的宏参数传递似乎是Cand的唯一解决方案?\u err
由\u expr
中的函数调用填充。请看问题中的最后一段代码。我明白了,这是一个非常丑陋的副作用。您肯定应该将status return变量的名称作为宏参数传递。如果是C++11,那么将表达式类型作为额外的宏参数传递似乎是Cand的唯一解决方案?