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

16

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

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

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

    
задан Xolve 23.07.2010 в 14:59
источник
  • Я думаю, что предложение нуждается в большем контексте. «Встроенная функция по-прежнему имеет уникальную переменную» не имеет смысла. Почему бы вам не подумать, что встроенная функция может иметь адрес? –  CB Bailey 23.07.2010 в 15:03
  • Какое издание? Я смотрю на третье издание и не вижу, где это сказано. –  Clifford 23.07.2010 в 15:09
  • Точная цитата из книги - «В частности, встроенная функция по-прежнему имеет уникальный адрес, а также статические переменные встроенной функции». Это последнее в разделе 7.1.1 - предыдущий параграф начинается с «Спецификатор inline - это подсказка для компилятора» (мой акцент). Статические переменные описаны в разделе 7.1.2 –  Steve314 23.07.2010 в 15:10
  • @Clifford - Я смотрю специальное издание (третье издание изменено) - старое издание специального издания третьего издания, в котором отсутствует приложение или два. Строуструп никогда, казалось, не осваивал идею увеличения номеров изданий. –  Steve314 23.07.2010 в 15:15
  • @Charles, исправлено, как указано. Спасибо :) –  Xolve 23.07.2010 в 19:13

6 ответов

35

Атрибут 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() ).

    
ответ дан Greg Hewgill 23.07.2010 в 15:03
  • +1. Очень хороший ответ. –  ereOn 23.07.2010 в 15:15
6

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

An inline function with external linkage shall have the same address in all translation units.

    
ответ дан Kirill V. Lyadvinsky 23.07.2010 в 15:03
  • Является ли это воплощением или связано с правилом «как будто»? –  jww 20.09.2016 в 15:15
5

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

    
ответ дан Scharron 23.07.2010 в 15:04
3

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

ответ дан Jerry Coffin 23.07.2010 в 15:03
0

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

ответ дан codymanix 23.07.2010 в 15:03
0

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

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

    
ответ дан Matt Joiner 23.07.2010 в 15:03