在main函数中重命名argc和argv是否安全

Is it safe to rename argc and argv in main function?

本文关键字:argv 是否 安全 argc 重命名 main 函数      更新时间:2023-10-16

许多程序对许多参数和字符串数组使用标准名称。主要功能的原型看起来像:int main(int argc, char *argv[]);。但是,如果我为这些变量选择自定义名称,我会破坏一些东西吗?

例如int main(int n_of_args, char *args[]);

在编译器的上下文中,一切都很好。这些变量是main函数的局部变量,所以它们可以有任何名称。简单的代码构建和运行都非常完美。但这些名称可能会被预处理器使用。那么重命名这些参数安全吗?

PS就我个人而言,我觉得这些名字很糟糕,因为它们看起来很相似,只有一个字母不同。但每个人都出于某种原因使用它们。

是的,只要使用有效的变量名,它是安全的。它们是局部变量,所以它们的作用域不会超出main函数。

来自C标准第5.1.2.2.1节:

程序启动时调用的函数名为main。这个实现没有声明该函数的原型。它应该定义为返回类型为int且无参数:

int main(void) { /*  ... */ }

或具有两个参数(此处称为argcargv尽管有可以使用名称,因为它们是所在函数的本地名称声明):

int main(int argc, char *argv[]) { /* ...   */ }

或同等产品;或者以某种其他实现定义的方式

也就是说,使用argcargv之外的任何东西都可能会让其他阅读代码的人感到困惑,因为他们习惯了这些参数的传统名称。所以最好还是站在聪明的一边。

名称argcargv实际上是C++标准在C++11之前强制要求的。声明称:

所有实施都应允许以下两个主要定义:

int main ()

int main ( int argc , char * argv [])

并对CCD_ 12和CCD_。

因此,从技术上讲,任何使用不同名称的程序都不符合标准,编译器可以拒绝它。当然,实际上没有编译器这样做。请参阅comp.std.c++上的此线程,或本c++03标准草案的第3.6.1节。

这几乎可以肯定只是一个疏忽,并在C++11中进行了更改,改为

所有实施均应允许

  • ()返回CCD_ 14和
  • 返回int的函数(int,指向char的指针的指针)

作为main(8.3.5)的类型。在后一种形式中,为了说明,第一个函数参数称为argc,第二个函数参数称为argv,…

当然,您可以根据的喜好安全地重命名这些参数

int main(int wrzlbrnft, char* _42[]) {
}

名字是用沙子写的。它们对最终编译的代码没有任何影响。


唯一重要的是,声明和定义的参数类型实际上是匹配的。

main()函数的签名本质上声明为

int main(int, char*[]);

如果您需要在实现中使用它们,实际上您需要命名它们。如前所述,使用哪些名称实际上是无关紧要的。

是。它很安全,看起来很奇怪,但不会打碎任何东西。

是的,使用不同的名称是安全的。

不过,就我个人而言,我不建议使用它,因为传统的argcargv对于其他可能使用过您的代码的C程序员来说是如此广为人知和熟悉。从长远来看,使用自己的、特殊的、不同的名字会在读者中引起更多的困惑和/或沮丧,因为你更喜欢自己的名字。

"入乡随俗。"

是的,您可以根据需要重命名它们。它们只是函数参数名称,仅此而已。

我觉得每个人都很好地涵盖了技术c++规则:答案是肯定的。让我们抛开传统,抛开这个1特殊功能是特殊的和标志性的这一事实,它包含了不在此基础上改变的有效点。

很多时候,我觉得选择的哲学很少被讨论,因此我想对这件事提供一个视角,因为我觉得这对为什么要求这样做很重要。

对我来说,这个问题涉及到用代码表达英语的一般选择。你似乎会被短手的描述所困扰,尤其是如果短手的文字看起来相似的话。然而,在您的示例中,将argn更改为n_of_args只完成了将一种类型的速记更改为另一种形式的速记,而没有实际的附加值:澄清或其他可见属性。

单词"number"已替换为字母"n"。

如果你通过反短手的哲学来更改短手的名字,那么这样的东西可能看起来更合适:

main(int argumentCount,char**argumentVector)

我总是考虑两件事:根据事物的本质和/或其隐含用法来命名事物。称它为argumentVector对我来说是多余的,因为作为向量的属性是由双向间接性**暗示的。因此,我将如何编写代码的一个更好的长手是:**参数。

有人会说,名为argumentCount的变量被声明为int,Count不能为负数,但可以为负数int{unsigned is better}。

同样,它是什么以及如何使用它在这种解释中发挥作用。如果它是一个计数,那么我认为它永远不会是负数。毕竟,你怎么能有一个计数为-2的苹果呢。我想说,你欠两个苹果。如果它是一个数字,那么我希望有可能出现阴性病例。这就是为什么额外的单词"of"对你来说可能很重要。这一点,也许还有集合所指的数字,意味着一个特定的项,而不是集合本身的属性。Ie:argumentsNumber=5表示一个特定的参数,而不是numberOfArguments。

main(int maxArgumentsIndex,char**arguments)。

这消除了歧义。将其称为索引可以消除大小写的歧义,还可以描述它是什么,以及如何使用它。它还暗示了英语措辞中的max是绝对的,如果编写修改这个值的代码(它应该是const),会感觉很奇怪。"arguments在这里是有意义的,因为它是复数,描述了它是什么,以及它应该如何使用。即使这样解释也可能很危险,因为Index是Count/NumberOf的-1。5个参数产生的maxIndex为4!!

任何其他功能,我都会完全使用:

void函数(const unsigned int maxArgumentsIndex,const char**自变量)

并不是所有的情况都值得用长手描述。事实上,有时短手会产生更高的可读性,尤其是在编写Vec3f、矩阵、四元数等数学类的情况下……我几乎总是试图匹配数学语言,而不是语言语言。浮动x,y,z vrs。float xComponent等。

我知道这一切都是一种风格选择,但从长远来看,意识到这些选择确实会有所帮助。我保证,当数组不是以复数形式编写时,经验丰富的程序员会感到烦恼,但话说回来,main是一种特殊的存在散文;)

根据C标准,可以重命名,不会有任何影响。正如我所理解的,在C语言中,默认的Keyword/types/token名称是根据目的/用法定义的,因此以相同的方式定义名称

argc --> argument count
argv --> argument vector

这在用法上也是有意义的,所以你可以更改为任何名称,除了Reserved names

在GCC中,程序执行从函数名main开始,这与他的参数无关。

当您为微控制器编写独立程序时,您不需要为名称main而烦恼,相反,您可以定义自己的name,并将Assembly entry_point更改为指向您的函数。这取决于控制器编译器和预定义控制器源代码的可用性。我在Code warrior下的Freescale控制器中做过这件事。

我的注意事项:

最好遵循通用标准/代码样式,使代码更可见和可读。

就编译器而言,这是安全的。

这可能造成的唯一问题是混乱。阅读代码的人会期望这两个变量有它们的标准名称。你甚至可以做这样的事情:

int main(int foo, char ** bar)
{
    int argc;
    float argv;

但我不认为我需要说明这将是多么糟糕的做法。

如果你不喜欢变量名,为什么不用宏#define:代替它们呢

#define yourCounterName argc
#define yourVectorName  argv 

您不会冒任何风险,生产出"清洁的解决方案"。