«Является ли класс для одной из ваших форм формой (например, переименованной из Формы1 в Форму)? Если это так, вам следует переименовать ее». @madreflection
Работало переименование формы из «Формы» в другое имя.
Во-первых, inline
спецификация на функции является просто подсказкой. Компилятор может (и часто делает), полностью игнорируют присутствие или отсутствие inline
спецификатор. После этих слов компилятор может встраивать рекурсивную функцию, хотя он может развернуть бесконечный цикл. Это просто должно установить границу на уровне, к которому это "развернет" функцию.
оптимизирующий компилятор мог бы повернуть этот код:
inline int factorial(int n)
{
if (n <= 1)
{
return 1;
}
else
{
return n * factorial(n - 1);
}
}
int f(int x)
{
return factorial(x);
}
в этот код:
int factorial(int n)
{
if (n <= 1)
{
return 1;
}
else
{
return n * factorial(n - 1);
}
}
int f(int x)
{
if (x <= 1)
{
return 1;
}
else
{
int x2 = x - 1;
if (x2 <= 1)
{
return x * 1;
}
else
{
int x3 = x2 - 1;
if (x3 <= 1)
{
return x * x2 * 1;
}
else
{
return x * x2 * x3 * factorial(x3 - 1);
}
}
}
}
В этом случае, мы в основном встроили функцию 3 раза. Некоторые компиляторы делают , выполняют эту оптимизацию. Я вспоминаю MSVC ++ наличие установки настраивать уровень встраивания, которое было бы выполнено на рекурсивных функциях (до 20, я верю).
Компилятор создает граф вызовов; когда цикл обнаруживается, называя себя, функция больше не встраивается после определенной глубины (n=1, 10, 100, независимо от того, что компилятор настраивается на).
AFAIK GCC сделает устранение последнего вызова на рекурсивных функциях, если это возможно. Ваша функция однако не является рекурсивным хвостом.
Действительно, если Ваш компилятор не действует разумно, он может попытаться вставить копии Вашего inline
функция d рекурсивно, создав бесконечно большой код. Большинство современных компиляторов распознает это, как бы то ни было. Они могут также:
Для случая 2, много компиляторов имеют #pragma
с, которую можно установить для определения максимальной глубины, на которую это должно быть сделано. В gcc, можно также передать это в от командной строки с --max-inline-insns-recursive
(см. больше информации здесь ).
Некоторые рекурсивные функции могут быть преобразованы в циклы, который эффективно бесконечно встраивает их. Я полагаю, что gcc может сделать это, но я не знаю о других компиляторах.
Компилятор сделает граф вызовов, чтобы обнаружить эти виды вещей и предотвратить их. Таким образом, это видело бы что вызовы функции само и не встроенное.
, Но главным образом этим управляют встроенное ключевое слово и переключатели компилятора (Например, у Вас может быть он автоматические встроенные небольшие функции даже без ключевого слова.) Его важное, чтобы отметить, что компиляции Отладки никогда не должны встраивать, поскольку стек вызовов не будет сохранен для зеркального отражения вызовов, которые Вы создали в коде.
См. ответы, уже данные для того, почему это не будет обычно работать.
Как "сноска", Вы могли достигнуть эффекта, который Вы ищете (по крайней мере, для факториала, который Вы используете в качестве примера), использование шаблонное метапрограммирование . Вставка из Википедии:
template <int N>
struct Factorial
{
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0>
{
enum { value = 1 };
};
"Как компилятор решает, встроить ли функцию или нет?"
, Который зависит от компилятора, опции, которые были указаны, номер версии компилятора, возможно, сколько памяти доступно, и т.д.
, исходный код программы все еще должен соблюсти правила для встроенных функций. Встраивается ли функция, необходимо подготовиться к возможности, что она будет встроена (некоторое неизвестное количество раз).
оператор Wikipedia, что рекурсивные макросы являются обычно недопустимыми взглядами, скорее плохо информированными. C и C++ предотвращают рекурсивные вызовы, но единица перевода не становится недопустимой, содержа макро-код, который похож на него, было бы рекурсивным. В ассемблерах рекурсивные макросы обычно законны.
Некоторые компиляторы (Т.е. Borland C++) не встраивают код, который содержит условные операторы (если, случай, в то время как и т.д.), таким образом, рекурсивная функция в Вашем примере не была бы встроена.