CUDA_SAFE_CALL中的do while(0)可以去掉吗?

CUDA_SAFE_CALL中的 do while(0)可以去掉吗?

建议LZ详细说下,目前这样没头没尾地出来一句,难度似乎可以和破译密码媲美。

-----------------------------------------------无敌分割线------------------------------------------------

看了3楼tianyuan08版主的回复,原来LZ问的是CUDA_SAFE_CALL这个宏定义中的内容。

此宏定义于cutil.h文件,在CUDA 4.X版本中,相关内容如下:

#  define CUDA_SAFE_CALL_NO_SYNC( call) {                                    \
   cudaError err = call;                                                    \
   if( cudaSuccess != err) {                                                \
   fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",        \
   __FILE__, __LINE__, cudaGetErrorString( err) );              \
   exit(EXIT_FAILURE);                                                  \
   } }

#  define CUDA_SAFE_CALL( call)     CUDA_SAFE_CALL_NO_SYNC(call);             

将函数的返回值(cudaError 类型)赋给同类型的变量err,然后使用cudaGetErrorString()函数得到该错误的描述,并且打印输出。
在这个版本的宏定义中,并无do-while循环的使用。

根据网上说法,在2.0版的CUDA中,相关内容是这样的:

# define CUDA_SAFE_CALL( call) do { \
  CUDA_SAFE_CALL_NO_SYNC(call); \
  cudaError err = cudaThreadSynchronize(); \
  if( cudaSuccess != err) { \
  fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \
  __FILE__, __LINE__, cudaGetErrorString( err) ); \
  exit(EXIT_FAILURE); \
  } } while (0)

这个大概是LZ问题的出处。
这个宏定义大致上依然是输出错误信息,只是一些实现方式不同。同时,这里的do-while(0)个人观点是有意只执行一次的意思,尚不清楚为何要这么写。

CUDA 2.0宏定义内容来源于此页面:
http://topic.csdn.net/u/20081121/16/8792ee94-9879-4f16-9ead-5e0d4fc8267a.html

从CUDA_SAFE_CALL的实现来看,do…while(0)并没有起到需要循环的作用,似乎只是为了能整体替换代码,所以我想应该是可以用其他方法来代替do while(0)

我继续对2楼和3楼的2位版主的回复进行一点补充。

这是一种常见的代码写作风格,其作用是
(1)为了对中途定义的、用到的变量的生存周期进行控制。
(2)为了在万一已有同名变量的情况下,能够shadow它,即再次可以定义一个同名变量。

在C语言里,在大括号里定义的普通变量,离开这个大括号后变得不再有效。在前文定义的变量,可以通过使用大括号再次定义(即黑话叫变量shadow)。

具体例子括号for,while, do…while, 直接的{}, 以及函数体的{}, 例如:
for(…) {…int 你的变量;…}
while(…) {…int 你的变量;…}
do{int 你的变量;} while(…);
{…int 你的变量;}
… your_function(…) {…int 你的变量;…}

具体到楼主的例子,特别根据2楼ICE大补充给出的现在和历史上的定义。此举为了防止在连续多次使用此宏,而导致的cudaError err;的重复错误, 也是为了避免前文已经防止定义了err而继续定义出错。 此外,楼主可以看到{ … }和do {…} while(false); 这是为了表明此语句块只是为了这些目的而写的,不是为了循环。

对楼主问题的回答:

正因为它有这些作用,所以不能去掉。

祝愿楼主代码写作愉快。