在阅读C ++中的函数时,我被教导函数需要调用声明。例如:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
它返回一个错误,因为没有函数sum
的声明。
main.cpp:4:36: error: use of undeclared identifier 'sum'
std::cout << "The result is " << sum(1, 2);
^
1 error generated.
要解决这个问题,我会添加声明:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
我的问题是,为什么我们不添加main
函数的声明,因为我们必须添加其他函数,如sum
?
函数的定义也是函数的声明。
声明函数的目的是让编译器知道它。在不定义函数的情况下声明函数允许在不方便定义函数的地方使用函数。例如:
B.h
)。在C ++中,用户程序从不调用main
,因此在定义之前永远不需要声明。 (请注意,如果你愿意,你可以提供一个。在这方面,main
的声明没有什么特别之处。)在C中,程序可以调用main
。在这种情况下,它确实要求在调用之前显示声明。
请注意,main
确实需要为调用它的代码所知。这是通常称为C ++运行时启动代码的特殊代码。当您将C ++程序与相应的链接器选项链接时,链接器会自动包含该代码。无论编写什么语言代码,它都需要main
的任何声明才能正确调用它。
我被教导说函数需要调用声明。
确实。必须先声明一个函数,然后才能调用它。
为什么我们不为
main
函数添加声明?
好吧,你没有调用main
函数。事实上,你不能在all1上调用main
,因此在任何事情之前都不需要声明main
。
从技术上讲,所有定义都是声明,所以你对main
的定义也声明了main
。
脚注1:C ++标准表示从程序中调用main
是未定义的行为。
这允许C ++实现将特殊的一次性启动代码放在main的顶部,如果它们不能让它从通常调用main
的启动代码中的钩子运行得更早。实际上,一些实际的实现确实这样做,例如,调用快速数学函数,设置一些FPU标志,如非正规零。
在假设的实现中,调用main可能会产生有趣的事情,例如重新运行所有静态变量的构造函数,重新初始化new
/ delete
使用的数据结构以跟踪分配或程序的其他完全破坏。或者它可能根本不会引起任何问题。未定义的行为并不意味着它必须在每次实现时都失败。
如果你想调用这个函数,那么原型是必需的,但它还没有,比如你的sum
。
你不能自己打电话给main
,所以不需要原型。编写原型甚至是一个坏主意。
不,编译器不需要main()
的前向声明。
main()
是C ++中的一个特殊功能。
关于main()的一些重要事项是:
main()
函数。int main () { /* body */ }
int main (int argc, char *argv[]) { /* body */ }
其中body
是零或更多的陈述
另一个可接受的形式是特定于实现的,并在调用函数时提供环境变量的列表:
int main (int argc, char* argv[], char *envp[]) { /* body */ }
编码人员必须使用其中一种可接受的形式提供主要的“定义”,但编码人员不需要提供声明。编码器定义被编译器接受为main()的声明。
return 0;
作为函数体中的最后一个语句。顺便说一句,有时混淆C ++程序是否可以调用main()。不建议这样做。 C ++ 17草案规定main()“不得在程序中使用”。换句话说,不能从程序内调用。参见例如Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66。我意识到一些编译器支持这个(包括我的),但是下一版本的编译器可以修改或删除该行为,因为标准使用术语“不应该”。
从程序内部调用main
是违法的。这意味着唯一要调用它的是运行时,编译器/链接器可以处理设置。这意味着你不需要main
的原型。
函数的定义也隐式声明了它。如果需要在定义函数之前引用它,则需要在使用之前声明它。
所以写下面的内容也是有效的:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
如果在一个文件中使用声明来在编译器定义之前使编译器知道某个函数,则必须在链接时知道它的定义:
main.cpp中
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
或者sum
可能源于一个库,所以你甚至不用自己编译它。
main
函数在代码中没有使用/引用,因此无需在任何地方添加main
的声明。
在main
函数之前和之后,c ++库可能会执行一些init和cleanup步骤,并将调用你的main
函数。如果库的那一部分将表示为c ++代码,那么它将包含int main()
的声明,以便可以编译它。该代码可能如下所示:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
但是你再次遇到与__main
相同的问题,所以在某些时候不再有c ++而且某个函数(main
)只代表你代码的入口点。
不。无论如何你不能打电话。
在定义函数之前,您只需要调用函数的前向声明。对于在其他文件中定义的函数,您需要外部声明(看起来与故意的前向声明完全相同)。
但你不能在C ++中调用main
所以你不需要它。这是因为允许C ++编译器修改main以进行全局初始化。
[我查看了crt0.c,它确实有一个main的声明,但它既不在这里也不在那里]。