Почему компилятор C99 не оптимизирует "! A && b" как "a <b" для логических значений? - PullRequest
0 голосов
/ 21 ноября 2018

Я видел этот действительно интересный твит :

, сопротивляющийся моему инстинкту игры в гольф, чтобы превратить if(!bool1 && bool2) в if(bool1<bool2)

У меня былоникогда раньше такого не видел, поэтому я хотел посмотреть, будут ли компиляторы использовать эту оптимизацию.Я запустил репозиторий с помощью README и тестовой программы на C: https://github.com/ndbroadbent/gcc_experiments

Вот тестовая программа:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

int main(int argc, const char* argv[]) {
  if(argc != 3) {
    printf("Usage: %s <a> <b>\n", argv[0]);
    exit(1);
  }
  bool a = strtol(argv[1], NULL, 10) != 0;
  bool b = strtol(argv[2], NULL, 10) != 0;

  if (!a && b) {
    printf("!a && b == true (a: %d, b: %d)\n", a, b);
  } else {
    printf("!a && b == false (a: %d, b: %d)\n", a, b);
  }
}

Я пытался скомпилировать эту программу как с gnu90, так и с C99 стандарты.Я знаю, что C99 имеет тип bool, но он все еще обрабатывается как целое число, поэтому компилятор не может выполнять какие-либо оптимизации на основе логической логики?

Возможно, я неправильно читаю сборку, но выглядиткак C99 с -O3 также включает в себя инструкции jne и je, вместо того, чтобы использовать только одну операцию «меньше» и одну инструкцию перехода.Похоже, что в C ++ эта оптимизация тоже не идет.

1 Ответ

0 голосов
/ 21 ноября 2018

Компиляторы хорошо знают об эквивалентности и могут оптимизировать на ее основе.Их идея о том, что должно быть оптимизировано до того, что могло бы быть противоположным вашему .

Для полноты, вот вывод сборки clang для функции, которая выполняет !a && b, а такжефункции, которая делает «a mov eax, edi not al and al, sil ret

...