__atomic_exchange_n 上的神秘 "value computed is not used" 警告
Mysterious "value computed is not used" warnings on __atomic_exchange_n
我基于 gcc 的原子内置函数开发了一个可重入函数。不幸的是,我收到关于 "computed but not used" 值的神秘警告:
$ gcc -c -Wall ss.c
ss.c: In function ‘ss_wrapper’:
ss.c:87:3: warning: value computed is not used [-Wunused-value]
__atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST);
^
ss.c:91:5: warning: value computed is not used [-Wunused-value]
__atomic_exchange_n(&ss_top, bkp->next, __ATOMIC_SEQ_CST); // release the lock, find out if there is new element
^
这是我的功能:
static void ss_wrapper(int signum, siginfo_t* siginfo, void *ucontext) {
// currently top element on the signal stack
static struct ss_hit* ss_top = NULL;
struct ss_hit* hit = ss_newhit(signum, siginfo, (ucontext_t*)ucontext);
struct ss_hit* bkp;
again:
bkp = hit;
__atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST);
if (!hit) { // we got the lock, we are the master
ss_fire(bkp);
// release the lock, find out if there is new element
__atomic_exchange_n(&ss_top, bkp->next, __ATOMIC_SEQ_CST);
if (bkp->next) { // there IS
hit = bkp;
free(bkp);
goto again;
} else
free(bkp);
} else { // we didn't got the lock, but we got the top in hit
__atomic_store(&hit->next, &bkp, __ATOMIC_SEQ_CST);
}
}
为什么会这样? __atomic_exchange_n
不应该计算任何东西,它只是交换两个变量的内容。
@Olaf 在评论中回答了我的问题:虽然用 __attribute__((unused))
声明一个虚拟变量并给他 return 值可以避免警告,但还有一种更简单的方法可以做到这一点: 将函数转换为 (void)
,因此:
(void)__atomic_exchange_n(...);
扩展:虽然这个解决方案也消除了警告,但它仍然没有正确使用 __atomic_exchange_n
gcc 内置(尽管有时它编译了正确的代码)。接受的答案最终解决了问题。
it only swaps the content of two variables
不,不是。它将一个变量的内容与寄存器的内容交换。第二个变量永远不会改变。 (即使不查阅文档,从传递两个参数的不同约定中也可以看出这一点——原子交换的内存地址作为指针传递,另一个值被复制,而不是就地访问)
由于这种误解,你的逻辑被打破了。你的意思是:
hit = __atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST);
if (!hit) { // we got the lock, we are the master
将寄存器的新值写回第二个变量。对 hit
的访问是非原子的,但这没关系,因为它是一个局部变量,不与任何其他线程共享。
不要只是扔掉return值,如果你这样做,你将永远不会进入"we are the master"
的分支
我基于 gcc 的原子内置函数开发了一个可重入函数。不幸的是,我收到关于 "computed but not used" 值的神秘警告:
$ gcc -c -Wall ss.c
ss.c: In function ‘ss_wrapper’:
ss.c:87:3: warning: value computed is not used [-Wunused-value]
__atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST);
^
ss.c:91:5: warning: value computed is not used [-Wunused-value]
__atomic_exchange_n(&ss_top, bkp->next, __ATOMIC_SEQ_CST); // release the lock, find out if there is new element
^
这是我的功能:
static void ss_wrapper(int signum, siginfo_t* siginfo, void *ucontext) {
// currently top element on the signal stack
static struct ss_hit* ss_top = NULL;
struct ss_hit* hit = ss_newhit(signum, siginfo, (ucontext_t*)ucontext);
struct ss_hit* bkp;
again:
bkp = hit;
__atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST);
if (!hit) { // we got the lock, we are the master
ss_fire(bkp);
// release the lock, find out if there is new element
__atomic_exchange_n(&ss_top, bkp->next, __ATOMIC_SEQ_CST);
if (bkp->next) { // there IS
hit = bkp;
free(bkp);
goto again;
} else
free(bkp);
} else { // we didn't got the lock, but we got the top in hit
__atomic_store(&hit->next, &bkp, __ATOMIC_SEQ_CST);
}
}
为什么会这样? __atomic_exchange_n
不应该计算任何东西,它只是交换两个变量的内容。
@Olaf 在评论中回答了我的问题:虽然用 __attribute__((unused))
声明一个虚拟变量并给他 return 值可以避免警告,但还有一种更简单的方法可以做到这一点: 将函数转换为 (void)
,因此:
(void)__atomic_exchange_n(...);
扩展:虽然这个解决方案也消除了警告,但它仍然没有正确使用 __atomic_exchange_n
gcc 内置(尽管有时它编译了正确的代码)。接受的答案最终解决了问题。
it only swaps the content of two variables
不,不是。它将一个变量的内容与寄存器的内容交换。第二个变量永远不会改变。 (即使不查阅文档,从传递两个参数的不同约定中也可以看出这一点——原子交换的内存地址作为指针传递,另一个值被复制,而不是就地访问)
由于这种误解,你的逻辑被打破了。你的意思是:
hit = __atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST);
if (!hit) { // we got the lock, we are the master
将寄存器的新值写回第二个变量。对 hit
的访问是非原子的,但这没关系,因为它是一个局部变量,不与任何其他线程共享。
不要只是扔掉return值,如果你这样做,你将永远不会进入"we are the master"
的分支