Comments 9
Современные оптимизирующие компиляторы вполне могут сами справиться с встраиванием функции в тело цикла
Не могу с ходу сообразить, а почему это не приведёт к возвращению исходной проблемы, с многократным вызовом alloca на одном и том же сегменте стека?..
Потому, что встраивание функции не означает, что это тоже самое, что подстановка макроса. Должны быть выполнены все те-же самые действия, что и при вызове функции.
Функции и макросы по-разному работают. Поясняющий пример:
#include <iostream>
struct A
{
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
#define MACROS A a;
void Function()
{
A a;
}
void UseMacros()
{
std::cout << "Используем макрос" << std::endl;
MACROS
std::cout << "Конец использования макроса" << std::endl;
}
void UseFunction()
{
std::cout << "Используем функцию" << std::endl;
Function();
std::cout << "Конец использования функции" << std::endl;
}
int main() {
UseMacros();
std::cout << "----------------" << std::endl;
UseFunction();
return 0;
}
Распечатает:
Используем макрос
A()
Конец использования макроса
~A()
----------------
Используем функцию
A()
~A()
Конец использования функции
В частности, после "выхода" из встроенной функции будет восстановлено то состояние стека, которое было до её "вызова", если я правильно понимаю?
Извините, я новичок в Си и в Плюсах, я изменил макоподстановку, и макрос заработал также, как и функция:
#include <iostream>
struct A
{
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
#define MACROS() do { \
A a; \
} while(false)
void Function()
{
A a;
}
void UseMacros()
{
std::cout << "Используем макрос" << std::endl;
MACROS();
std::cout << "Конец использования макроса" << std::endl;
}
void UseFunction()
{
std::cout << "Используем функцию" << std::endl;
Function();
std::cout << "Конец использования функции" << std::endl;
}
int main() {
UseMacros();
std::cout << "----------------" << std::endl;
UseFunction();
return 0;
}
Вывод:
[?2004l
Используем макрос
A()
~A()
Конец исп�льзования макроса
----------------
Используем функцию
A()
~A()
Конец использования функции
[?2004h
В этом коде макрос с функцией также работают одинаково:
#include <iostream>
struct A
{
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
#define MACROS() ({ \
A a; \
})
void Function()
{
A a;
}
void UseMacros()
{
std::cout << "Используем макрос" << std::endl;
MACROS();
std::cout << "Конец использования макроса" << std::endl;
}
void UseFunction()
{
std::cout << "Используем функцию" << std::endl;
Function();
std::cout << "Конец использования функции" << std::endl;
}
int main() {
UseMacros();
std::cout << "----------------" << std::endl;
UseFunction();
return 0;
}
Логично. Теперь объект разрушается, когда завершается его область видимости, ограниченная фигурными скобками.Только это имеет перпендикулярное отношение к рассматриваемой теме. Внимательно читаем описание функции alloca
. Самое важное:
Выделенная с использованием
alloca
память автоматически освобождается при выходе из функции, которая вызвалаalloca
.
в сортировке получается нету проверки есть ли +1 итем, тоесть можно выйти за пределы
у java удобно, нексты в синтаксисе С++ тоже на итераторы можно повесить такие обращения, скорость будет чуть медленнее зато будет чуть гарантия и удобнее
типо std::advance, std::next/prev/distance тут классные комбинации по удалению/вставке на шаблоны классно подходят, я такое делал ток в 2д в пазлере
интересно, как аллоцирует буфер для замены элементов qsort()
Следующая публикация: Учимся рефакторить код на примере багов в TDengine, часть 3: плата за лень.
Завершение цикла публикаций про TDengine - Необходимость статического анализа для РБПО на примере 190 багов в TDengine.
Учимся рефакторить код на примере багов в TDengine, часть 2: макрос, пожирающий стек