2015-09-10 3 views
3

Рассмотрим классический способ определения факториала:Force встраивание рекурсивной функции

#include <stdio.h> 

__attribute__((always_inline)) inline int factorial(int n) 
{ 
    if (n == 1){ 
     return 1; 
    } else { 
     return n * factorial(n - 1); 
    } 
} 

int main() 
{ 
    printf("value %d", factorial(7/*guaranteed to not overflow int*/)); 
} 

Я принуждая мой компилятор (GCC) встраивать функцию факториала. То, что должно вызвать проблему. gcc игнорирует мою силу inline без ошибок. Ожидается ли это?

+2

Рекурсивная функция не может быть встроенными функциями. Я думаю, что компилятор игнорирует ваш «атрибут» из-за этого – Astinog

+1

@Agostino: Если вы читаете вопрос, OP это знает, поэтому он спросил об этом ... – Melkon

+0

Поскольку вы назвали factorial с константой, откуда вы ее знаете не было включено? Я не знаю, является ли gcc таким умным. Когда я тестировал icc много лет (и версии назад), это было не так уж и умно (такая оптимизация констант произошла после, а не смешанная с inlining). Но, возможно, gcc теперь умнее, чем icc. – JSF

ответ

2

Из документации GCC по:

GCC не встраивать какие-либо функции, когда не оптимизируя, если не указать атрибут always_inline для функции.

Так что always_inline не означает «встроить это или диагностировать», это означает «встроенный, даже если оптимизация отключена». Он все равно откажется в чем-то, если это невозможно или разумно.

Как вы можете видеть here, для примера, такого же простого, как у вас, вся функция может быть оптимизирована и результат вычисляется во время компиляции. Даже если аргумент не является константой времени компиляции, функция все равно может быть inlined. Рекурсия не всегда сделать вставка невозможно.

Однако, если вы указали Floris Velleman, если вы отключите его, будет fail to compile, указав, что функция не рассматривается для встраивания, даже если она будет включена, если оптимизация включена. Похоже, что фактическая обработка атрибута не полностью соответствует документации.

+1

Хороший ответ, интересно, как это приводит к ошибке времени компиляции, если вы собираетесь скомпилировать ее без оптимизации, похоже, что 'constexpr' лучше подходит, если вам приходится работать с константами времени компиляции. –

+0

@FlorisVelleman Да, вы правы, это странно. – TartanLlama

Смежные вопросы