c - 内联定义

标签 c inline

pg474,K.N. King

"The general rule in C99 is that if all top-level declarations of a function in a particular file include inline but not extern, then the definition of the function in that file is inline."


  • 什么是“函数的顶级声明”?

  • "If the function is used anywhere in the program (including the file that containts its inline declaration), then an external declaration of the function will need to be provided by some other file. When the function is called, the compiler may choose to perform an ordinary call (using the function's external definition) or perform inline expansion (using the function's inline definition). There's no way to tell which choice the compiler will make, so it's crucial that the two definitions be consistent."


  • 他在这里说什么?

  • "Variables with static storage duration are a particular problem for inline functions with external linkage"



    但我认为您无法通过外部链接调用函数!这
    编译器会给出一个错误:

    第473页

    "so attempting to call average from another file will be considered an error"

    "Consequently, C99 imposes the following restrictions on an inline function with external linkage (but not on one with internal linkage): The function may not define a modifiable static variable. The function may not contain references to variables with internal linkage."



    为什么??如果函数是内联函数和extern ,则即使它确实声明了一个
    静态诠释由于该函数无法链接,因此无法调用它,
    但不会在内联函数外部创建静态变量
    堆栈框架-因此您应该能够链接到它?进行内联功能
    有一个堆栈框架?这里发生了什么??

    最佳答案

    我知道我写了很多书,但是我尝试在解释文本的同时解释存储和链接的概念。希望这可以帮助!

    "The general rule in C99 is that if all top-level declarations of a function in a particular file include inline but not extern, then the definition of the function in that file is inline."

    What is a: "top-level declaration of a function"??



    函数的声明的用法类似于变量的声明。这是一个声明函数的名称,返回类型和参数类型的语句。函数定义是该函数的实际代码。

    声明示例:
    int foo( int bar );
    

    定义示例:
    int foo( int bar ){
        return -bar;
    }
    

    顶层函数声明只是在文件范围内(即,在任何块之外)的声明。尽管可以在其他函数中声明和定义函数,但这通常是所有函数声明所在的地方。

    "If the function is used anywhere in the program (including the file that containts its inline declaration), then an external declaration of the function will need to be provided by some other file. When the function is called, the compiler may choose to perform an ordinary call (using the function's external definition) or perform inline expansion (using the function's inline definition). There's no way to tell which choice the compiler will make, so it's crucial that the two definitions be consistent."

    Huh??? What is he saying here??



    首先,什么是联系?变量或函数的链接定义了编译器将如何处理该对象的多个实例。没有链接的标识符始终是“个人”。也就是说,程序中标识符的多个声明始终被视为单独的/不同的实体。函数参数和局部变量没有链接。对带有外部链接的标识符的所有引用均指同一实体。这是C关键字“extern”。默认情况下,全局标识符具有外部链接。这意味着,例如,如果您具有全局变量“int x;”。在程序的两个源文件中,它们将被链接在一起并被视为相同的变量。内部链接意味着一个源文件中标识符的所有声明都引用一个实体,而其他源文件中相同标识符的声明则引用了不同实体。这是将事物“私有(private)化”到文件的C方法。这是文件范围中的C关键字“静态”。

    现在,回到该段。一个函数不能被多次定义。因此,要使用其他源文件中的函数的源文件需要包含一个外部声明(这是进行函数调用所需的信息)。本段说明的内容是,当文件对内联函数进行外部声明时会发生什么。编译器必须选择是否应获取内联定义,并将其插入到调用函数的位置,或者是否应保留外部链接,从而使执行像通常一样跳转到代码文本;而且没有办法预测编译器将做出的选择。

    "Variables with static storage duration are a particular problem for inline functions with external linkage"

    But i thought you couldn't call a function with external linkage! The compiler would give an error: pg 473 "so attempting to call average from another file will be considered an error"



    如果您无法调用在其他源文件中定义的函数(即外部链接函数),则C确实是一种非常弱和无聊的语言!

    "Consequently, C99 imposes the following restrictions on an inline function with external linkage (but not on one with internal linkage): The function may not define a modifiable static variable. The function may not contain references to variables with internal linkage."

    Why?? If a function is inline and extern, then even if it does declare a static int i; since the function can't be linked to you can't call it, but won't a static variable be created outside the inline functions stack-frame - so you should be able to link to it? Do inline functions have a stack frame? What's going on here??



    静态存储的 变量是不属于执行堆栈的变量。在程序开始运行之前,它的空间分配了一次,并且在整个执行过程中都存在。他们保留其初始值,直到分配了其他值。默认情况下,全局变量(文件作用域)是静态存储的。这与自动存储的变量相反,后者在程序执行进入声明它们的块之前在堆栈上分配,并在执行离开该块时被丢弃。默认情况下,局部变量(块作用域)是自动的。

    回到问题:内联函数内部的静态存储变量有什么问题?函数中的静态存储变量的生存假设是该函数只有一个定义,因此该静态变量只有一个定义。但是根据定义,内联是对函数定义的重复,因此您在函数调用期间无需在代码文本中跳转。如果函数中存在静态变量,那么您将不得不跳到其存储位置,从而无法实现内联的目的,即要在其中“拥有”所有内容的副本。解决方案:要求该变量不可修改,以便编译器可以内联永久值。

    关于您的最后一个问题:内联函数的确有一个堆栈框架:它与调用函数是相同的堆栈框架,因为要复制内联函数的代码文本,以避免正常的外部函数跳转的标准指令开销。

    关于c - 内联定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8454690/

    相关文章:

    c - Valgrind 给出了不正确的行号

    c - C中链表函数的 append (添加到尾部)打印不正确(不打印最后 append 的元素)

    compiler-construction - 自动抽取函数如何识别相似表达式?

    html - 向一系列显示内联 div 标签添加 margin top 或 padding top

    c++ - 使用 C 或 C++ 的微 Controller

    c - 当所有值都有效时如何终止可变长度数组?

    python - 动态规划递归求解

    函数调用内的javascript内联注释

    html - 添加了显示 :inline-block, 但我的 HTML 元素仍然溢出到不同的行

    html - 具有宽度值的内联 img 标签