是声明函数,然后在C / C ++中定义它的内联法律?

在C和/或C ++中以下是合法的吗?

void fn();

inline void fn()
{
  /*Do something here*/
}

令我担心的是,第一个声明看起来像是暗示该函数将被定义为非内联函数,但下面的定义将其转化为内联函数。

如果在这种情况下C和C ++之间存在差异,那么也很高兴知道这种差异。


是。 实际上,这可能是最好的。 资料来源:http://www.parashift.com/c++-faq/inline-nonmember-fns.html

经验法则:声明告诉你如何调用一个函数并使用它的返回值。 定义说,当你打电话时会发生什么。 你可以改变一个函数的内联和后退,而不用修改你的调用方式,所以它是定义的一部分是有意义的。 (当然,有意义的东西并不总是匹配的,所以这只是一个规则。)


在ISO C ++(非成员函数)

只有代码实际出现在头文件中才可以,如图所示。 如果头文件包含非内联声明,但是inline定义不会出现在所有的翻译单元中,这将是未定义的行为(不需要诊断); 即使该函数未被调用。

参考:C ++ 14 [dcl.fct.spec] / 4(注意定义也是一个声明):

如果一个具有外部链接的功能在一个翻译单元中内联申报,则应在其出现的所有翻译单元中内联申报; 不需要诊断。

在ISO C ++(成员函数)

如果代码出现在类定义中,那么它就可以,并且inline关键字是多余的,因为出现在类定义中的函数定义是隐式inline

如果类定义包含void fn(); 然后有一个行外定义inline void Class::fn() { ,行为与非成员大小写相同。

在ISO C中

C11 6.7.4 / 7:

如果翻译单元中的某个函数的所有文件范围声明都包含不带externinline函数说明符,则该翻译单元中的定义是内联定义。

非内联声明的存在意味着后面的定义不是内联定义,尽管它具有inline关键字。 所以定义实际上是一个外部定义(即相同的链接属性,就好像它没有标记为inline )。

因此,如果此代码出现在由两个翻译单元包含的头文件中,由于多个外部定义,它是未定义的行为; 但是如果原型在标题中并且定义位于包含该标题的一个翻译单元中,则可以。

注意:GNU C inlineinline ISO C不同。 我不确定这个代码在GNU C中的定义行为。


内联函数是编译器将函数定义中的代码直接复制到调用函数的代码中,而不是在内存中创建单独的一组指令的函数。 除了将控制权交给功能代码段或从功能代码段转移控制权之外,功能体的修改副本可以直接替代函数调用。 这样就避免了函数调用的性能开销。

C除main之外的任何函数都可以声明或定义为与内联函数说明符内联。 不允许在内联函数的主体中定义静态局部变量。

在类声明中实现的C ++函数是内联自动定义的。 在main声明之外声明的常规C ++函数和成员函数可以声明或定义为与内联函数说明符内联。 在内联函数体内定义的静态局部和字符串文字被视为跨翻译单元的同一对象。

内联函数说明符

结论

C ++

类:你的两个函数本质上都具有相同的原型。 然而,由于第一个函数将嵌入到类中,因此它与定义的内联函数处于不同的范围。 因此它会没事的。

非类:如果您没有将非内联函数嵌入到类中,则它将被视为重定义错误,并会产生编译错误。 因为它预计超载,但原型是相同的。

C

C与C ++变体对于非Classes相同。 因此,如果你像在你的问题中那样在.c文件中定义它,编译器会给你一个重定义错误。 喜欢:

redefinition of 'fn 

和/或注释:

previous definition of 'fn' was here
链接地址: http://www.djcxy.com/p/75379.html

上一篇: Is declaring the function and then defining it inline legal in C/C++?

下一篇: Spell Checking With Redactor On Heroku