6

Допустим, у меня есть простая функция, как это:короткозамкнутых операторов и хвостовая рекурсия

int all_true(int* bools, int len) { 
    if (len < 1) return TRUE; 
    return *bools && all_true(bools+1, len-1); 
} 

Эта функция может быть переписана в более очевидно хвостовой рекурсии стиля следующим образом:

int all_true(int* bools, int len) { 
    if (len < 1) return TRUE; 
    if (!*bools) return FALSE; 
    return all_true(bools+1, len-1); 
} 

Логично, что между ними существует нулевая разница; при условии, что bools содержит только TRUE или FALSE (разумно определено), они делают то же самое.

Мой вопрос: если компилятор достаточно умен, чтобы оптимизировать второй как хвостовой рекурсии вызова, это разумно ожидать, что для оптимизации первого таким же образом, учитывая, что «& &» короткого замыкания? Очевидно, если бы использовался оператор без короткого замыкания, это было бы не быть хвостовым рекурсивным, потому что оба выражения были бы оценены до того, как оператор будет применен, но мне любопытно случай короткого замыкания.

(Перед тем как получить поток комментариев, рассказывающих мне, что компиляторы C обычно не оптимизируют хвостовые рекурсивные вызовы: рассмотрим это как общий вопрос об оптимизации хвостовых рекурсивных вызовов с операторами короткого замыкания, независимо от языка. Я буду рад переписать это в Scheme, Haskell, OCaml, F #, Python или о том, что черт вам когда-нибудь еще, если вы не понимаете C.)

+0

gcc оптимизирует рекурсивные вызовы. – Arafangion

ответ

2

Ваш вопрос действительно «насколько умен компилятор ?» но вы не указываете, какой компилятор вы используете.

Учитывая гипотетический разумный компилятор, который преобразует исходный код промежуточного графа потока перед тем оптимизаций, как фрагменты кода, которые вы написали могут быть представлены таким же образом (оператор & &, в то время как удобно печатать, не почти как тривиально скомпилированный как оператор &, поэтому я не удивлюсь, если он будет расширен в одной фазе на гипотетическом компиляторе). Исходя из этого предположения, разумно утверждать, что ответ на ваш вопрос «да».

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