这是我对函数声明和定义的了解。如果有任何问题,请纠正我。
// Function Declaration
// This is usually put in .h header file
int occur (const char* sentence, const char& achar);
// Function Definition
// This is usually put in .cpp
int occur (const char* sentence, const char& achar) { // do job and return }
我正在阅读" C ++ Primer第5版"。在"内联和constexpr函数@ Chapter 6.5.2 P.240"下,它说
与其他函数不同,可以定义内联函数和constexpr函数 多次参加该计划。
我脑子里想出了类似的东西:
// function delcaration .h file
constexpr int returnfour();
// function definition in .cpp file
constexpr int returnfour () { return 4; }
constexpr int returnfour () { return 4; }
拥有像这样的多个定义是否正确? defined multiple times in the program
意味着什么,有人想什么时候做?
答案 0 :(得分:2)
与其他功能不同,
inline
和constexpr
功能可在程序中多次定义。
假设您有a.h:
inline int foo() { return 10; }
constexpr int bar() { return 20; }
现在,您#include
了几个.cpp
文件中的文件。
file1.cpp:
#include "a.h"
// ... other functions
file2.cpp:
#include "a.h"
// ... other functions
int main() { return 0; }
编译这些文件时,函数foo
和bar
在file1.cpp的目标代码中定义,以及file2.cpp的目标代码。链接这些目标代码以创建可执行文件时,foo
和bar
分别有两个定义。这是合法的。
但是,不允许在同一编译单元中对同一inline
函数或constexpr
函数进行多个定义。
使用:
inline int foo() { return 10; }
inline int foo() { return 10; }
或
constexpr int bar() { return 20; }
constexpr int bar() { return 20; }
单个cpp文件中的是不合法的。
答案 1 :(得分:1)
函数声明向编译器提供有关函数名称,它接受的参数的数量和类型以及返回值的信息。编译器使用此信息来检查尝试调用该函数的语句。
函数定义是一种特定类型的声明,它还包含实现函数的复合语句(函数体的}
和inline
之间的部分)。
关于具有多个定义的constexpr
和inline
函数的声明并不意味着该定义可以在单个编译单元中重复多次。 C ++有一个单独的编译模型,因此在编译另一个编译单元时,编译器不能在一个编译单元中看到函数定义。但是,多个编译单元可以分别定义constexpr
或#include
函数(例如,通过每个constexpr
相同的标题。如果不同的编译单元具有相同功能的非等效定义,则整个程序的结果是未定义的。这样做的结果是inline
和{{1}}函数的代码可能在程序中重复(例如,在多个位置内联,不内联,但在目标文件中以不可见的方式在本地实现其他编译单元等)由编译器(通常与构建链的其他部分一起工作)来确保在编译单元之间以一致的方式发生这种情况。
答案 2 :(得分:0)
如上所述,可以多次定义内联和constexpr函数。但它们应该只在每个编译单元中定义一次。通过扩展,如果您在标头中定义它们并在多个编译单元中包含标头,则它们只能在头文件中定义一次。 注意:它们也应具有相同的签名,否则行为未定义。
内联函数和constexpr函数都在编译时解析,这就是为什么只要你不违反编译单元中的ODR(一个定义规则)就可以在编译单元之间有多个定义
请参阅C ++标准文档中的相关摘录:
7.1.5 constexpr说明符
constexpr函数和constexpr构造函数是隐式的 内联函数(7.1.2)。
3.2单一定义规则
每个程序都应该包含每个非内联函数或odr使用的变量的一个定义 在该计划中;无需诊断。定义可以在程序中明确显示,可以找到 在标准或用户定义的库中,或(在适当的时候)它是隐式定义的(见12.1,12.4和 12.8)。内联函数应在每个使用它的翻译单元中定义。