使用函数调用作为参数的 C 错误检查宏定义不会在 MSVC 上编译

标签 c visual-c++ macros opencl

我正在尝试使用一些针对 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”。我有点不知所措。我可以忘记它并跳过错误检查,但我想了解出了什么问题......

最佳答案

CL_CHECK_EXPR() 宏对我来说似乎不正确:

  • _err 的测试应该总是失败,因为 CL_INVALID_VALUE 应该不同于 CL_SUCCESS

  • 我想 _err 应该派生自 _expr,但正如它所写的那样,它没有功能。

  • typeof 缺乏可移植性的一个简单解决方法是将实际类型作为宏参数传递。 C 不支持像在 C++ 中那样使用 auto 关键字推断类型。

  • 此外,您的编译器可能不支持表达式语句扩展,让您别无选择。

您可能应该更改要包含在此类宏中的内部 API,以始终返回错误代码并使用指针参数返回正常结果。

关于使用函数调用作为参数的 C 错误检查宏定义不会在 MSVC 上编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33939343/

相关文章:

c++ - GetModuleHandle(NULL) 与 hInstance

qt - vs2013 编译用于调试但不用于发布?

c++ - 在 MSVC 2010 中编译 64 位应用程序

C 中的大小写可变宏

c - 该行的指针解释宏

c - 宏中的可变参数

c - 如何修改 C 程序以便 gprof 可以分析它?

c - 预生成的公共(public)/私有(private) RSA key ,无法在 C 中解密(在 python 中工作)

c++ - 有没有办法在命令行获得可读的 gcc 错误和警告输出?

c - 使用无符号倒数的正确方法