c - ISO C 是否允许对提供给 main() 的 argv[] 指针使用别名?

标签 c parameter-passing language-lawyer alias c11

ISO C 要求托管实现调用名为 main 的函数.如果程序接收参数,它们将作为 char* 的数组接收。指针,main 中的第二个参数的定义 int main(int argc, char* argv[]) .

ISO C 还要求 argv 指向的字符串数组是可修改的。

但是argv的元素可以吗?互为别名?换句话说,是否存在i , j这样

  • 0 >= i && i < argc
  • 0 >= j && j < argc
  • i != j
  • 0 < strlen(argv[i])
  • strlen(argv[i]) <= strlen(argv[j])
  • argv[i]别名 argv[j]

在程序启动时?如果是这样,写通 argv[i][0]也可以通过别名字符串 argv[j] 看到.

ISO C 标准的相关条款如下,但不允许我最终回答标题问题。

§ 5.1.2.2.1 Program startup

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

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

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

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

or equivalent; 10) or in some other implementation-defined manner.

If they are declared, the parameters to the main function shall obey the following constraints:

  • The value of argc shall be nonnegative.
  • argv[argc] shall be a null pointer.
  • If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
  • If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.
  • 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.

根据我的阅读,标题问题的答案是"is",因为没有任何地方明确禁止它,标准也没有任何地方敦促或要求使用 char* restrict* -合格argv ,但答案可能取决于对“并在程序启动和程序终止之间保留它们最后存储的值。”的解释。

这个问题的实际含义是,如果答案确实是"is",那么一个希望修改 argv 中的字符串的可移植程序必须首先执行(相当于)POSIX strdup()为了安全起见。

最佳答案

By my reading, the answer to the titular is "yes", since nowhere is it explicitly forbidden and nowhere does the standard urge or require the use of restrict-qualified argv, but the answer might turn on the interpretation of "and retain their last-stored values between program startup and program termination.".

我同意该标准没有明确禁止参数 vector 的元素互为别名。我不认为可修改性和值(value)保留条款与该立场相矛盾,但它们确实向我表明委员会没有考虑别名的可能性。

The practical import of this question is that if the answer to it is indeed "yes", a portable program that wishes to modify the strings in argv must first perform (the equivalent of) POSIX strdup() on them for safety.

的确,这正是我认为委员会甚至没有考虑这种可能性的原因。如果他们这样做了,那么他们肯定至少会包含一个具有相同效果的脚注,或者明确指定参数字符串都是不同的。

我倾向于认为这个细节没有引起委员会的注意,因为在实践中,实现确实提供了不同的字符串,而且因为程序很少修改它们的参数字符串(尽管修改 argv 本身更常见)。如果委员会同意在该领域发布官方解释,那么我不会对他们反对使用别名的可能性感到惊讶。

但是,除非发布这样的解释,否则您是对的,严格的一致性不允许您先验 argv 元素没有别名。

关于c - ISO C 是否允许对提供给 main() 的 argv[] 指针使用别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50779748/

相关文章:

javascript - 将带有 2 个参数的函数传递给 addEvent Listener 方法

javascript - 在 Vue.js 中传递参数

c++ - 外参数包可以用内参数包展开推导吗?

c++ - std::string(itr, itr) 应该做什么?

c++ - 在 C++11 标准中,它在哪里禁止 'template <typename T> class A {...}; template <typename T> class A<int> {...};'(如果有的话)?

c - 严格符合 ANSI C 的 ON/OFF 模式的不同结果

c - Linux 中的 Pthread

python - 如何解决使用Python ctypes调用rs232.c时出现段错误的问题?

c - 当指针未知时,如何释放 C 中的内存?

c++ - 是否可以在函数调用中构造和传递数组/其他容器?