我在学习“Unix编程环境”(1983)中的一些例子时,读过一些特殊的C-代码。
作为一种好奇心,我想了解更多关于它的,让我们称之为“风格”。这里感兴趣的是int main(argc, argv)下面的线
#include <stdio.h>
int main(argc, argv)
char *argv[];
{
printf("%s\n", argv[0]);
return 0;
}在我的研究中,我发现用-Wall -pedantic -ansi标志编译上面的代码是没有任何警告的,用最近的-std=c99 (或c11,用gcc和cc)代替-ansi只会警告argc默认为int。
我仔细阅读了旧的C89标准,试图找到对这种特殊写作方式的引用,但没有找到任何单独的东西,所以我遵从集体的更多知识。
因此,问题是,这种深奥的写作是什么时候开始的,可能是为什么它仍然被允许(遗留的原因?)
发布于 2014-06-25 18:34:44
做事情的老方法是没有原型的功能。函数默认返回int,而且由于调用站点中的函数参数类型未知,所以最好将其正确。这使您不必维护头文件,但出于各种原因,不再建议使用该文件。
// In func.c
// Default to int return
func(x, y)
int x;
int y;
{
return x + y;
}
// In main.c
main(argc, argv)
int argc;
char **argv;
{
int result = func(2, 3);
}如果函数参数类型错误,则会导致问题。
int result = func(2.0, 3,0); // Wrong, but no compiler error or warning调用函数而不包括相关的头文件是正常的。但是您需要声明函数返回类型。
// This is NOT a function prototype, it just declares the return type.
double sin();
double one = sin(3.14); // Correct
double zero = sin(0); // WRONG
double zero = sin(0.0); // Correct标准仍然允许使用旧的样式函数,除非默认的返回类型已经消失。这允许您编译旧程序。对于新的程序,GCC中的-Wmissing-prototypes选项可以帮助您避免偶然地使用旧风格。
int func(); // Old-style, can take any number of arguments.
int func(void); // New-style, takes no arguments, is a function prototype.发布于 2014-06-25 18:29:21
这是很好的老式K&R C。
默认情况下,所有内容都是整数,您可以在函数中定义参数的实际类型,而不是在原型中,而是在单独的声明列表中。它使只编写整数的代码更容易编写,但却使调试函数调用成为噩梦。
下面是用这两种样式编写的函数。
int myFunc(const char *from, char *to, int len); // Ah that feels right, doesn't it
int myFunc(const char *from, char *to, int len){} // And here's the definition
myKRFunc(); /* Okay, that's a declaration */
myKRFunc(from, to, len) /* Yep, you just write the parameter names here */
char *from, *to; /* And you can write normal declarations, len defaults to an int */
{}我想解释为什么在没有原型的情况下调试函数调用比较困难,但是Dietrich在他的回答中很好地介绍了它。
发布于 2014-06-25 18:29:58
这是最初的K&R风格。它仍然是合法的,因为为什么不呢?向后兼容性允许人们以小步前进。这就是任何流行的进化系统所带来的痛苦。
https://stackoverflow.com/questions/24415872
复制相似问题