猿问

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

链接器对此报告重复的符号:


#ifndef testttt

#define testttt


void anything(){

    std::cout<<"hellooooooo";

}


#endif

因为它在include防护内部,所以我希望此函数只定义一次。但显然不是。


我知道我可以static在它前面加上这个词,然后它就会起作用(我仍然觉得很讽刺,因为应该将static赋予它内部链接,但是可以从多个cpp文件中使用该函数)。


因此,我想我的问题分为两部分:1)为什么包含保护不像其他标头项那样阻止该函数的多个定义,以及2)为什么static当应该假定静态名称阻止名称可见时,单词会解决此问题吗?在其他翻译单位中?我添加了它,实际上可以从包含此头文件的任何位置调用此函数。


哔哔one
浏览 427回答 3
3回答

皈依舞

“ 1)为什么包含保护不能像其他标题项那样阻止该功能的多个定义”因为每个翻译单元(即.cpp文件)都是分别处理的,并且要经过相同的条件。翻译单元不会共享其他翻译单元遇到的预处理器定义。这意味着将处理该标头的所有翻译单元都将包含该函数的定义。当然,链接器随后会抱怨同一函数具有多个定义。“ 2)当应该使用静态词来防止名称在其他翻译单元中可见时,为什么静态词会解决此问题?”因为static关键字为每个翻译单元制作了该功能的私有副本。但是,如果您希望在共享头文件中定义该函数,则应将其标记为inline,这将解决您的问题并使不必要的预处理器防护。

潇湘沐

1)为什么包含保护不能像其他标题项那样阻止该功能的多个定义,包含保护可防止在同一转换单元中多次包含标头。但是,它不能防止出现多个定义:如果标头包含在多个翻译单元中,则将存在多个定义错误,因为该函数是在每个翻译单元中定义的,并且由于它具有外部链接,因此所有翻译单元都可以请参阅所有其他翻译单元的定义。为防止发生此错误,您只需在标头中提供声明,并在一个文件中提供定义.cpp。阅读有关一个定义规则(ODR)和外部链接的信息。2)当应该使用静态词来防止名称在其他翻译单元中可见时,为什么静态词会解决此问题?因为static使函数在每个翻译单元内部均有效。这就是内部链接的含义:其他翻译单元看不到定义。
随时随地看视频慕课网APP
我要回答