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); 这是为了表明此语句块只是为了这些目的而写的,不是为了循环。
对楼主问题的回答:
正因为它有这些作用,所以不能去掉。
祝愿楼主代码写作愉快。