Проверка во время компиляции, является ли сдвиг вправо арифметическим для подписанных типов

Мне интересно, каков наиболее переносимый способ проверить, является ли сдвиг вправо арифметическим при работе со знаковыми типами (например, -2 >> 1 равно ] -1 ) во время компиляции.

Моя идея состоит в том, чтобы как-нибудь проверить это во время компиляции и иметь возможность это обнаружить, Проверка того, что сдвиг вправо со знаком C / C ++ является арифметическим для конкретного компилятора? Мне пришла в голову идея инициализировать флаг

static const bool is_arithmetic_rs = (((signed int)-1)>>1) == ((signed int)-1));

и протестировать его во время выполнения следующим образом:

if (is_arithmetic_rs) {
  // some fast algorithm using arithmetic right shifts (using >> operator)
} else {
  // the same algorithm without arithmetic right shifts (much slower)
}

Однако я хотел бы каждый раз по возможности избегать этого ветвления. Для простоты предположим, что я хочу реализовать переносимый арифметический сдвиг вправо; если бы мне пришлось проверять это каждый раз при вызове функции, это оказало бы огромное влияние на производительность, поэтому я хотел бы делать это во время компиляции, если это возможно.

Если не существует переносимого способа выполнения этой проверки, это есть ли способ сделать это, проверив, насколько это возможно, например, с помощью ifdef для конкретного компилятора / платформы?

5
задан Community 23 May 2017 в 10:28
поделиться