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

问题描述 投票:80回答:10

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

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

在编译器的上下文中,一切都很好。这些变量对于main函数是本地的,因此它们可以具有任何名称。简单的代码构建和运行完美。但这些名称可能由预处理器使用。那么重命名这些论点是否安全?

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

c++ c main
10个回答
117
投票

是的,只要您使用有效的变量名称,它就是安全的。它们是局部变量,因此它们的范围不超出main函数。

来自C standard的第5.1.2.2.1节:

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

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

或者有两个参数(这里称为argcargv,虽然可以使用任何名称,因为它们是声明它们的函数的本地名称):

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

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

话虽这么说,使用除了argcargv以外的任何东西可能会让其他人阅读你习惯于这些参数的传统名称的代码混淆。因此,在犯罪方面更好地犯错。


-1
投票

如果您不喜欢变量名称,为什么不用宏#define替换它们:

#define yourCounterName argc
#define yourVectorName  argv 

您不会冒任何风险并产生“清洁解决方案”。


37
投票

名称argcargv实际上是在C ++ 11之前由C ++标准强制执行的。它说:

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

int main ()

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

并继续讨论对argcargv的要求。

因此从技术上讲,任何使用不同名称的程序都不符合标准,并允许编译器拒绝它。当然,没有编译器实际上这样做了。参见this thread on comp.std.c++,或this C++03 draft standard的第3.6.1节。

这几乎肯定只是一种疏忽,并且在C ++ 11中有所改变,而C ++ 11则更改了

所有实现都应允许两者

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

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


28
投票

当然,您可以根据需要安全地重命名这些参数

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

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


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

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

 int main(int, char*[]);

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


15
投票

是。这是安全的,看起来很奇怪,但它不会破坏任何东西。


7
投票

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

就个人而言,我不会推荐它,因为传统的argcargv是如此广为人知,并且对于可能使用您的代码的其他C程序员来说都很熟悉。从长远来看,使用您自己的,特殊的,不同的名称将导致您的读者更加困惑和/或挫折,因为您更喜欢自己的名字。

“在罗马做到入乡随俗。”


5
投票

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


3
投票

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

很多时候,我觉得选择的哲学很少被讨论,因此我想提供一个关于这个问题的观点,因为我觉得这个问题的起因很重要。

对我来说,这个问题涉及一般在代码中表达英语的选择。你似乎对简短的描述感到困扰,特别是如果简短的手上有相似的文字。在您的示例中,将argn更改为n_of_args仅实现将一种类型的短手更改为另一种形式的速记而没有实际值添加:澄清或其他可见属性。

'number'一词已被字母'n'取代。

如果你是通过反短手的哲学改变一个简短的名字,那么这样的事情似乎更合适:

main(int argumentCount,char ** argumentVector)

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

有人会说名为argumentCount的变量被声明为int而Count不能为负,但你可以有一个负的int {unsigned更好}。

同样,它是什么以及如何使用它来解释这个问题。如果它是一个伯爵,那么我认为它永远不会是负面的。毕竟,你怎么能有-2个苹果的数量。我会说,你吃了两个苹果。如果是一个数字,那么我认为可能会出现负面情况。这就是为什么附加单词'of'对你很重要。那个,也许一个集合所引用的数字意味着一个特定的项目,而不是一个集合本身的属性。即:argumentsNumber = 5意味着一个特定的参数,但不是numberOfArguments。

main(int maxArgumentsIndex,char ** arguments)。

这消除了歧义。将其称为索引可消除负面情况模糊,并描述它是什么,以及如何使用它。它还暗示了英语的措辞,max是绝对的,并且会觉得奇怪的编写代码来修改这个值(它应该是const)。 'arguments'在这里有意义,因为它是复数,描述它是什么,以及它应该如何使用。即使以这种方式解释也可能是危险的,因为索引是Count / NumberOf的-1。 5个参数产生的maxIndex为4 !!

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

void function(const unsigned int maxArgumentsIndex,const char ** arguments)

并非所有情况都值得长手描述。事实上,有时候一只简短的手会产生更多的可读性,特别是在编写数学类如Vec3f,Matrix,Quaternion等的情况下......我几乎总是试图匹配数学语言而不是语言语言。浮动x,y,z vrs。 float xComponent等。

我知道所有这些都是一种风格选择,但从长远来看,意识到这些选择确实会有所帮助。我保证经验丰富的程序员在数组不是以复数形式写的时候会受到打扰,但是再次,主要是存在的特殊散文;)


2
投票

根据C标准,是的,您可以重命名,没有任何影响。据我所知,在C语言中,默认的关键字/类型/令牌名称是用目的/用法定义的,因此它以相同的方式定义名称

argc --> argument count

argv --> argument vector

这在使用方面也有意义,因此您可以更改为任何名称,期望Reserved names

在GCC中,程序执行以函数名称main开始,它不依赖于他的参数。

当您为微控制器编写独立程序时,您无需担心名称main,而是可以定义自己的name并更改Assembly entry_point以指向您的函数。它取决于控制器编译器和预定义控制器源代码的可用性。我在Code-warrior下的飞思卡尔控制器中做过这个。

我的注意:

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


0
投票

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

这可能导致的唯一问题是混乱。阅读代码的人会希望这两个变量具有标准名称。你甚至可以这样做:

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

但我认为我不需要说出这种做法有多糟糕。

© www.soinside.com 2019 - 2024. All rights reserved.