У встроенных функций есть адреса?
В разделе 7.1.1 книги "Язык программирования С++" автор утверждает:
"встроенная функция по-прежнему имеет уникальный адрес, а также статические переменные встроенной функции
Я смущен. Если у меня есть встроенная функция, она не может иметь адрес. Это также происходит в C?
Ответы
Ответ 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. Обычно мы визуализируем встроенные функции как помещенные в вызывающую функцию на уровне исходного кода. Что говорится в книге, так это то, что имена переменных, в том числе использование статических внутри встроенных функций, обрабатываются так же, как если бы эта функция была на самом деле вашей типичной автономной функцией.
Кроме того, обработка функций с помощью встроенного ключевого слова не гарантирует, что они будут встроены, а в тех случаях, когда они не могут (например, когда требуется адрес), будет создана неинсталлированная версия.