我一直在思考最简单地用C语言表达主要功能的最诚实的方式(是的,这很简单,通常没有意思,但对我来说很有趣)。
很长一段时间,直到今天,我更喜欢将main定义如下:
int main(int argc, char **argv)
{
return 0;
}
我的问题是我通常从不使用这些参数,所以它使参数显式化,即使我在代码中不够关心它们来写出它们。
所以我开始做
int main()
{
return 0;
}
这是诚实的,因为它没有明确说明该函数没有参数,就像int main(void){}
定义中的许多参数一样,并且我对它感到满意。
然而,我只是想到使用main的可变参数定义使得main的定义对我来说更舒服,因为它“看起来”对我来说好像函数确实有参数,但我现在不关心它们
int main(...)
{
return 0;
}
对......的这种滥用符号是否存在任何问题?也就是说,......意味着用于模式的函数(,可以推导出以下参数数量的参数,......)。虽然这个主要不符合这种模式,但在技术上是滥用符号。
我理解这种符号会误导其他读者(...有点是一种先进的概念,被滥用会使其更具误导性),在共享代码时我仍然会更喜欢其他原型。我只是好奇C是否有效。
我的问题是:
主要是可移植的可变参数定义,还是某些编译器可能不喜欢它。
通常可以做这种定义,还是运行/编译时的后果?
答案 0 :(得分:4)
不,那是绝对错误。
这是错误的,因为它是无效的语法。从n1548第6.7.6节:
parameter-type-list:
parameter-list
parameter-list , ...
parameter-list:
parameter-declaration
parameter-list , parameter-declaration
根据C标准,如果在函数参数中使用...
,则必须至少有一个其他参数。其他任何内容都无效C.您可以从语法中看到...
只能出现在逗号,
和参数列表之后,以及参数列表< / em>不能为空。
您的编译器可能会接受它,但这并不意味着什么。编译器接受许多无效的C并且无论如何都要愉快地编译它们。
答案 1 :(得分:1)
你的前两个版本没问题。使用符合您需求的任何一种。
int main(...)
不会是这个功能的好签名,即使它有效!
...
表示该函数采用可变数量的未指定类型的参数。以printf()
为例。它接收一个格式字符串,后跟零个或多个任何类型的参数,其函数签名反映了这一点:
int printf( const char* format, ... )
main
功能不是那样的。它接收特定类型的参数的特定列表,而不是具有必须在运行时确定的类型的可变数量的参数。
传统上,main
采用了两个参数,如第一个示例所示:
int main( int argc, char **argv )
当然,您可以通过不使用它们或通过在第二个示例中定义main来忽略这些参数:int main()
。
根据编译器/运行时,main
可能会采用包含环境变量的第三个参数:
int main( int argc, char *argv[], char *env[] )
甚至可能在OSX上采取第四个论点:
int main( int argc, char **argv, char **envp, char **apple )
但在所有这些情况下,您都有特定类型的特定参数。 main
并不像printf
- 它永远不会使用真正的变量不确定类型的参数。所以main(...)
不是合适的签名。