Загадочные предупреждения "вычисленное значение не используется" в __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 встроен правильно (хотя иногда он компилирует правильный код). Принятый ответ наконец решает проблему.

Другие вопросы по тегам