“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.”
为什么??如果函数是内联函数和外部函数,那么即使它确实声明了一个函数
static int i;由于功能无法链接到你无法调用它,
但是不会在内联函数之外创建静态变量
堆栈框架 – 所以你应该能够链接到它?做内联函数
有一个堆栈框架?这里发生了什么??
解决方法
“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;”在程序的两个源文件中,它们将链接在一起并视为同一个变量.内部链接意味着一个源文件中的标识符的所有声明都引用单个实体,但是其他源文件中的相同标识符的声明引用不同的实体.这是使文件“私有”的C方式.这是文件范围中的C关键字“static”.
现在,回到段落.函数不能定义多次.因此,想要使用其他源文件中的函数的源文件需要包含外部声明(这是进行函数调用所需的信息).本段解释的是当文件具有内联函数的外部声明时会发生什么.编译器必须选择是否应该获取内联定义并将其插入调用函数的位置,或者是否应该保留外部链接,使执行跳转到代码文本,就像正常一样;并且没有办法预测编译器将做出什么选择.
“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??
静态存储的变量是不属于执行堆栈的变量.它的空间在程序开始运行之前分配一次,并在整个执行过程中存在.它们保留其初始值,直到分配不同的值.默认情况下,全局变量(文件范围)是静态存储的.这与自动存储的变量形成对比,自动存储的变量在程序执行进入声明它们的块之前在堆栈上分配,并且在执行离开该块时被丢弃.默认情况下,局部变量(块范围)是自动的.
回到问题:内联函数中静态存储变量的问题是什么?函数内的静态存储变量的假设是该函数只有一个定义,因此只有该静态变量的一个定义.但是,根据定义,内联是函数定义的重复,因此您不需要在函数调用期间跳转代码文本.如果函数中存在静态变量,那么你将不得不跳转到它的存储位置,从而无法实现内联的目的,即拥有“就在那里”的所有内容的副本.解决方案:要求变量不可修改,以便编译器可以内联永久值.
关于你的最后一个问题:内联函数确实有一个堆栈框架:它与调用函数的堆栈框架相同,因为内联函数的代码文本正在被复制,以避免正常外部函数跳转的标准指令开销.