Загадочные предупреждения "вычисленное значение не используется" в __atomic_exchange_n
Я разработал реентерабельную функцию, основанную на атомарных встроенных функциях gcc. К сожалению, я получаю загадочные предупреждения о "вычисленных, но не используемых" значениях:
$ 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
не должен ничего вычислять, он только меняет содержимое двух переменных.
2 ответа
это только меняет содержимое двух переменных
Нет. Он заменяет содержимое одной переменной на содержимое регистра. Вторая переменная никогда не изменяется. (Даже без ознакомления с документацией, это очевидно из разного соглашения о передаче двух параметров - адрес памяти, который атомарно обменивается, передается как указатель, другое значение копируется, а не используется на месте)
В результате этого недоразумения ваша логика нарушена. Вы хотели сделать:
hit = __atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST);
if (!hit) { // we got the lock, we are the master
который записывает новые значения регистра обратно во вторую переменную. Доступ к hit
не атомарны, но это нормально, потому что это локальная переменная, не используемая другим потоком.
Не просто выбрасывайте возвращаемое значение, если вы это сделаете, вы никогда не войдете в ветку "мы хозяин"
@Olaf ответил на мой вопрос в комментарии: хотя объявите фиктивную переменную с __attribute__((unused))
и возвращая ему значения, вы избегаете предупреждений, но есть и более простой способ сделать это: приведение функций к (void)
, так:
(void)__atomic_exchange_n(...);
Расширение: хотя это решение также устраняет предупреждение, оно по-прежнему не использует __atomic_exchange_n
GCC встроен правильно (хотя иногда он компилирует правильный код). Принятый ответ наконец решает проблему.