Подтвердить что ты не робот

У встроенных функций есть адреса?

В разделе 7.1.1 книги "Язык программирования С++" автор утверждает:

"встроенная функция по-прежнему имеет уникальный адрес, а также статические переменные встроенной функции

Я смущен. Если у меня есть встроенная функция, она не может иметь адрес. Это также происходит в C?

4b9b3361

Ответ 1

Атрибут inline - это всего лишь подсказка для компилятора, что он должен попытаться встроить вашу функцию. По-прежнему можно взять адрес функции, и в этом случае компилятору также потребуется испустить не встроенную версию.

Например:

#include <stdio.h>

inline void f() {
    printf("hello\n");
}

int main() {
    f();
    void (*g)() = f;
    g();
}

Вышеприведенный код дважды печатает hello.

Мой gcc компилятор (с -O) испускает код примерно так:

_main:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $20, %esp
        call    ___i686.get_pc_thunk.bx
"L00000000002$pb":
        leal    LC0-"L00000000002$pb"(%ebx), %eax
        movl    %eax, (%esp)
        call    L_puts$stub        ; inlined call to f()
        call    L__Z1fv$stub       ; function pointer call to f() (g is optimised away)
        movl    $0, %eax
        addl    $20, %esp
        popl    %ebx
        popl    %ebp
        ret

Как вы можете видеть, сначала появляется вызов puts(), а затем вызов L__Z1fv() (который является искаженным именем f()).

Ответ 2

В строковых функциях есть адреса, если они вам нужны. Стандарт только говорит, что:

Встроенная функция с внешним ссылка имеет тот же адрес в все единицы перевода.

Ответ 3

Нет противоречия. В тех частях, где вызывается встроенная функция, ее код может быть встроен. В тех частях, где вы используете указатель на функцию, можно создать не встроенную версию, чтобы иметь адрес.

Ответ 4

Встроенное расширение функции не имеет адреса, но если эта функция имеет статическую переменную, переменная имеет адрес. Статическая переменная - это просто глобальная переменная, имя которой видимо только локально (I.e., в пределах области, в которой она определена). Другие переменные в встроенной функции могут быть выделены в стеке (например, они были бы, если бы они не были расширены встроенными), или они могут просто жить в машинных регистрах. Важная часть состоит в том, что они все еще являются отдельными переменными и должны действовать так же, как функция не была полностью развернута внутри (в отличие, например, от макросов, где требуется особая осторожность, чтобы предотвратить многочисленные проблемы, вызывающие проблемы).

Ответ 5

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

Ответ 6

Я думаю, вы сбиваете с толку местоположение кода объекта встроенных функций, с последствиями inlining. Обычно мы визуализируем встроенные функции как помещенные в вызывающую функцию на уровне исходного кода. Что говорится в книге, так это то, что имена переменных, в том числе использование статических внутри встроенных функций, обрабатываются так же, как если бы эта функция была на самом деле вашей типичной автономной функцией.

Кроме того, обработка функций с помощью встроенного ключевого слова не гарантирует, что они будут встроены, а в тех случаях, когда они не могут (например, когда требуется адрес), будет создана неинсталлированная версия.