为了账号安全,请及时绑定邮箱和手机立即绑定

为什么包括防护不阻止多个功能定义?

为什么包括防护不阻止多个功能定义?

C++
哔哔one 2019-12-21 11:19:21
链接器对此报告重复的符号:#ifndef testttt#define testtttvoid anything(){    std::cout<<"hellooooooo";}#endif因为它在include防护内部,所以我希望此函数只定义一次。但显然不是。我知道我可以static在它前面加上这个词,然后它就会起作用(我仍然觉得很讽刺,因为应该将static赋予它内部链接,但是可以从多个cpp文件中使用该函数)。因此,我想我的问题分为两部分:1)为什么包含保护不像其他标头项那样阻止该函数的多个定义,以及2)为什么static当应该假定静态名称阻止名称可见时,单词会解决此问题吗?在其他翻译单位中?我添加了它,实际上可以从包含此头文件的任何位置调用此函数。
查看完整描述

3 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

“ 1)为什么包含保护不能像其他标题项那样阻止该功能的多个定义”

因为每个翻译单元(即.cpp文件)都是分别处理的,并且要经过相同的条件。翻译单元不会共享其他翻译单元遇到的预处理器定义。这意味着将处理该标头的所有翻译单元都将包含该函数的定义。当然,链接器随后会抱怨同一函数具有多个定义。

“ 2)当应该使用静态词来防止名称在其他翻译单元中可见时,为什么静态词会解决此问题?”

因为static关键字为每个翻译单元制作了该功能的私有副本。

但是,如果您希望在共享头文件中定义该函数,则应将其标记为inline,这将解决您的问题并使不必要的预处理器防护。


查看完整回答
反对 回复 2019-12-21
?
潇湘沐

TA贡献1816条经验 获得超6个赞

1)为什么包含保护不能像其他标题项那样阻止该功能的多个定义,


包含保护可防止在同一转换单元中多次包含标头。但是,它不能防止出现多个定义:如果标头包含在多个翻译单元中,则将存在多个定义错误,因为该函数是在每个翻译单元中定义的,并且由于它具有外部链接,因此所有翻译单元都可以请参阅所有其他翻译单元的定义。为防止发生此错误,您只需在标头中提供声明,并在一个文件中提供定义.cpp。


阅读有关一个定义规则(ODR)和外部链接的信息。


2)当应该使用静态词来防止名称在其他翻译单元中可见时,为什么静态词会解决此问题?


因为static使函数在每个翻译单元内部均有效。这就是内部链接的含义:其他翻译单元看不到定义。


查看完整回答
反对 回复 2019-12-21
  • 3 回答
  • 0 关注
  • 426 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信