将main定义为int main(...){}

时间:2016-04-09 21:29:38

标签: c

我一直在思考最简单地用C语言表达主要功能的最诚实的方式(是的,这很简单,通常没有意思,但对我来说很有趣)。

很长一段时间,直到今天,我更喜欢将main定义如下:

int main(int argc, char **argv)
{
    return 0;
}

我的问题是我通常从不使用这些参数,所以它使参数显式化,即使我在代码中不够关心它们来写出它们。

所以我开始做

int main() 
{
    return 0;
}

这是诚实的,因为它没有明确说明该函数没有参数,就像int main(void){}定义中的许多参数一样,并且我对它感到满意。

然而,我只是想到使用main的可变参数定义使得main的定义对我来说更舒服,因为它“看起来”对我来说好像函数确实有参数,但我现在不关心它们

int main(...)
{
    return 0;
}

对......的这种滥用符号是否存在任何问题?也就是说,......意味着用于模式的函数(,可以推导出以下参数数量的参数,......)。虽然这个主要不符合这种模式,但在技术上是滥用符号。

我理解这种符号会误导其他读者(...有点是一种先进的概念,被滥用会使其更具误导性),在共享代码时我仍然会更喜欢其他原型。我只是好奇C是否有效。

我的问题是:

  1. 主要是可移植的可变参数定义,还是某些编译器可能不喜欢它。

  2. 通常可以做这种定义,还是运行/编译时的后果?

2 个答案:

答案 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(...)不是合适的签名。