Гарантируется ли, что компилятор C ++ не будет генерировать переход, если условие зависит от типа шаблона и известно во время компиляции? - PullRequest
0 голосов
/ 30 июня 2018

Предположим, у меня есть эта функция:

template<typename Side>
int GetSide(std::pair<int, int> i)
{
    if (Side::mIsLeft)
        return i.first;
    else
        return i.second;
}

Я вижу, что если mIsLeft равно const (даже не constexpr), компилятор (gcc / clang) не будет генерировать какую-либо ветку:

int GetSide<LeftSide>(std::pair<int, int>):
  push rbp
  mov rbp, rsp
  mov QWORD PTR [rbp-16], rdi
  mov eax, DWORD PTR [rbp-16]
  pop rbp
  ret

В отличие от того, когда mIsLeft был НЕ const, какая ветвь будет сгенерирована (как и ожидалось).

Теперь мой вопрос: это поведение (не генерирующее ветку) обеспечивается стандартом или гарантировано в любом случае? Или это просто компилятор видит возможность и использует ее? (это генерируется даже в -O0) Что если mIsLeft будет constexpr, это что-нибудь изменит?

Вы можете проверить код здесь, на кресте .

Почему меня это волнует? Прежде чем найти это, в такой ситуации я бы использовал enable_if и имел две разные специализации шаблона, чтобы избежать ненужной ветви, но это может упростить много кода.

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Нет, стандарт не определяет, как компиляторы должны генерировать код. Компиляторам разрешено создавать ветви, даже если условие является константой времени компиляции.

С другой стороны, в наши дни оптимизирующие компиляторы делают все возможное, чтобы удалить ненужные ветви, поэтому это может считаться ошибкой компилятора, если основанная на постоянной времени компиляции if не будет оптимизирована.

0 голосов
/ 30 июня 2018

Детали вашего конкретного случая нам не полностью известны, но в целом ответ отрицательный. Конечно, переменная const может быть инициализирована чем-то, что не известно во время компиляции, например, пользовательский ввод.

Вам следует использовать значение constexpr и проверку if constexpr (если это возможно в вашей кодовой базе).

...