Я использовал оба этих компилятора в разных проектах.Разница между clang и gcc
Как они отличаются с точки зрения обработки кода и выходных поколений? Например, как gcc
, так и clang
имеет -O2
варианты оптимизации. Они работают одинаково (на высоком уровне) с точки зрения оптимизации кода? Я сделал небольшой тест, например, если у меня есть следующий код:
int foo(int num) {
if(num % 2 == 1)
return num * num;
else
return num * num +1;
}
являются следующие выходные сборки с лязгом и НКУ с -O2:
----gcc 5.3.0----- ----clang 3.8.0----
foo(int): foo(int):
movl %edi, %edx movl %edi, %eax
shrl $31, %edx shrl $31, %eax
leal (%rdi,%rdx), %eax addl %edi, %eax
andl $1, %eax andl $-2, %eax
subl %edx, %eax movl %edi, %ecx
cmpl $1, %eax subl %eax, %ecx
je .L5 imull %edi, %edi
imull %edi, %edi cmpl $1, %ecx
leal 1(%rdi), %eax setne %al
ret movzbl %al, %eax
.L5: addl %edi, %eax
movl %edi, %eax retq
imull %edi, %eax
ret
, как это можно видеть на выходе имеет разные инструкции. Поэтому мой вопрос заключается в том, имеет ли одно из них преимущество перед другим в разных проектах?
Вы можете улучшить свой код, написав 'int foo (int num) {return num * num + ~ num & 1;}' вместо этого. – fuz
@FUZxxl: замечательная точка, которая [делает намного лучший код] (https://godbolt.org/g/Y1RZuj), но вам нужно использовать parens 'int foo (int num) {return num * num + (~ num & 1);} 'потому что' & 'имеет более низкий приоритет, чем * и +. Кроме того, это имеет различное поведение для отрицательных чисел. В C, -1% 2'' '-1', поэтому if является ложным. если вы пишете 'n * n + (n% 2)'. –
@FUZxxl спасибо за примечание, это просто простой тест, чтобы увидеть, какие компиляторы выводят то, что – Pooya