Pull to refresh

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()

Sign up to leave a comment.