是指向字符串argv中修改? [英] Are the pointers to strings in argv modifiable?

查看:147
本文介绍了是指向字符串argv中修改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

近日(2016年1月,如果这个问题仍然存在足够长的时间),我们有问题<一href=\"http://stackoverflow.com/questions/35102922/are-the-strings-in-argv-modifiable/35102948?noredirect=1#comment57931629_35102948\">Are argv中修改字符串?。结果
在注释部分来这个的答案,我们(@ 2501和我)认为是否真的在串字符(一个例子字符是 ** argv的),这是修改或指向字符串(一个例子指针是 * argv的)。

Recently (Jan 2016, in case the question persists long enough) we had the question Are the strings in argv modifiable?.
In the comment section to this answer, we (@2501 and I) argued whether it is really the strings of characters (an example character being **argv) that's modifiable or the pointers to the strings (an example pointer being *argv).

相应的标准报价是N1570的C11标准草案,§5.1.2.2.1/ 2:

The appropriate standard quotation is from the C11 standard draft N1570, §5.1.2.2.1/2:

参数 ARGC 的argv 和字符串的指向
  的argv 阵列应作案网络能够通过该程序,并保留其
  程序启动和终止程序的最后存储的值。

The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

那么,由指着指向字符串的argv 修改?

So are the pointers to the strings as pointed to by argv modifiable?

推荐答案

由于OP在问题中的说明,C11标准明确规定, ARGC 的argv 变量,由的argv 阵列指向的字符串,是可以修改的。无论这些指针修改与否,是眼下的问题。该标准似乎并没有明确说明它的一种方式或其他。

As OP quoted in the question, the C11 standard explicitly states that the argc and argv variables, and the strings pointed by the argv array, are modifiable. Whether those pointers are modifiable or not, is the question at hand. The standard does not seem to explicitly state it one way or the other.

有需要注意标准的措辞两个关键点:

There are two key points to note about the wording in the standard:


  1. 如果指针被认为是不可变的,标准可能都清楚,要求主要的声明为 INT主(INT ARGC,char * const的的argv []),因为 haccks在另一个回答这个问题提到

事实上,无处标准是常量关联提到与的argv 似乎经过深思熟虑的。也就是说,缺乏常量的似乎不可选的,但被标准所决定的。

The fact that nowhere in the standard is const mentioned in association with argv seems deliberate. That is, the lack of const does not seem optional, but dictated by the standard.

该标准要求的argv 一贯的阵列。修改数组是指修改其成员。因此,它似乎很明显,在标准的措辞指修改的argv 数组中的成员,当它说的argv 可修改

The standard calls argv consistently an array. Modifying an array refers to modifying its members. Thus, it seems obvious that the wording in the standard refers to modifying the members in the argv array, when it states that argv is modifiable.

在另一方面,阵列的参数的在C(基于C11 N1570草案,§6.7.6.3p7)的应调整为合格指向类型。因此,下面的code,

On the other hand, array parameters in C (based on C11 draft N1570, §6.7.6.3p7) "shall be adjusted to 'qualified pointer to type'". Thus, the following code,

int foo(int x[2], int y[2])
{
    if (x[0] > y[0])
        x = y;
    return x[1];
}

是有效的C11,因为 X 调整为 INT * X INT * Y ,分别为。 (这也重申了C11 N1570草案,§6.3.2.1p3:... ...数组转换为类型指针类型指向的初始元素的前pression阵......的)。
 显然,同样也不会,如果 X 被声明为局部或全局的阵列,而不是函数的参数。

is valid C11, since x and y are adjusted to int *x and int *y, respectively. (This is also reiterated in C11 draft N1570, §6.3.2.1p3: "... array ... is converted to an expression with type 'pointer to type' that points to the initial element of the array ...".) Obviously, the same would not be, if x and y were declared as local or global arrays, not function parameters.

至于语言lawyerism去,我会说标准并没有说明它这种或那种方式,虽然它的意味着的指针也应该是可修改的。因此,作为一个答案OP:两个

As far as language-lawyerism goes, I'd say the standard does not state it one way or another, although it implies the pointers too should be modifiable. Thus, as an answer to OP: both.

在实践中,有一个很长的的argv 数组是一个可修改的指针的传统。许多图书馆有一个指针指向 ARGC 初始化函数和一个指向的argv 阵,其中一些办修改的argv 数组的指针(除去具体到库选项);例如 GTK + gtk_init() MPI_INIT() (虽然至少的openmpi明确指出它不检查或修改它们)。寻找参数声明(INT ARGC *,烧焦***的argv);这样做的唯一原因 - 假设的意图是从所谓的main()使用(安培; ARGC,&安培; argv的) - 是修改指针,解析和命令行参数删除库特定的命令行参数,修改这两个 ARGC 和指针在的argv 需要。

In practice, there is a very long tradition of the pointers in the argv array being modifiable. Many libraries have initialization functions that take a pointer to argc and a pointer to the argv array, and some of them do modify the pointers in the argv array (removing options specific to the library); for example GTK+ gtk_init() and MPI_Init() (although at least OpenMPI explicitly states it does not examine or modify them). Look for parameter declaration (int *argc, char ***argv); the only reason for this -- assuming the intent is to be called from main() using (&argc, &argv) -- is to modify the pointers, to parse and remove the library-specific command-line parameters from the command-line parameters, modifying both argc and the pointers in argv as needed.

(本来我说,<一个href=\"http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html\"><$c$c>getopt()在POSIX设施的依赖的上的指针被修改 - 该功能可追溯至1980年,大多数Unix系统采用,并于1997年在POSIX.2标准 - 不过这是不正确,因为乔纳森·莱弗勒指出出评论:POSIX getopt的()不修改实际的指针;只有GNU getopt的()呢,和它仅在未设置 POSIXLY_CORRECT 环境变量,两者GNU getopt_long()和BSD getopt_long()修改指针,除非 POSIXLY_CORRECT 设置,但他们更年轻,更少wides $ p $垫相比 getopt的()

(I originally stated that the getopt() facility in POSIX relies on the pointers being modifiable -- the feature dating back to 1980, adopted by most Unix flavours, and standardized in POSIX.2 in 1997 -- but that is incorrect, as Jonathan Leffler pointed out in a comment: POSIX getopt() does not modify the actual pointers; only GNU getopt() does, and it only when the POSIXLY_CORRECT environment variable is not set. Both GNU getopt_long() and BSD getopt_long() modify the pointers unless POSIXLY_CORRECTis set, but they are much younger and less widespread compared to getopt().)

在Unix的土地上,它被认为是便携修改字符串指向的内容由的argv [] 阵列的并修改字符串在进程列表中可见的。如何这是有用的一个例子是在DJB的daemontools的包, readproctitle 。 (请注意,串将具有就地进行修改,并且可以不被延长,以使更改是在进程列表可见。)

In the Unix land, it was considered "portable" to modify the contents of the strings pointed to by argv[] array, and have the modified strings visible in the process list. One example of how this was useful is in DJB's daemontools package, readproctitle. (Note that the strings would have to be modified in-place, and cannot be extended, for the changes to be visible in the process list.)

这一切都说明了一个非常悠久的传统,基本上差不多,因为C的诞生作为编程语言,绝对preceding治疗的C的标准化, ARGC 的argv 的argv 数组的指针,和字符串的内容指向这些指针,可修改

All this indicates a very long tradition, basically almost since the birth of C as a programming language, and definitely preceding the standardization of C, of treating argc, argv, the pointers in the argv array, and the contents of the strings pointed to by those pointers, as modifiable.

由于C标准的目的不是定义新的行为,但编纂现有的不同实现的行为(促进便携性和可靠性等方面),似乎可以认为,这是一个意外的疏忽对标准的一部分作家没有明确指定的argv 数组作为修改的指针。还有什么会打破传统,并明确地违背了POSIX标准(这也是为了促进整个系统的可移植性,并扩展C特性不包括在ISO C标准)。

Because the intent of the C standard is not to define new behaviour, but codify existing behaviour across implementations (to promote portability and reliability and so on), it seems safe to assume that it was an unintended omission on part of the standard writers to not explicitly specify the pointers in the argv array as modifiable. Anything else would break tradition, and be explicitly contrary to the POSIX standard (which is also intended to promote portability across systems, and extends C features not included in the ISO C standard).

这篇关于是指向字符串argv中修改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆