gpt4 book ai didi

c - 将非数组变量的地址传递给声明为 `Type ptr[static 1]` 的函数参数是否有效?

转载 作者:行者123 更新时间:2023-12-03 14:37:51 25 4
gpt4 key购买 nike

如前所述 here , herehere以这种方式定义的函数(在 c99 或更新版本中)

void func(int ptr[static 1]){
//do something with ptr, knowing that ptr != NULL
}
有一个指向 int 类型指针的参数( ptr ),编译器可以假设该函数永远不会以 null 作为参数被调用。 (例如,编译器可以优化空指针检查,或者在使用空指针调用 func 时发出警告 - 是的,我知道,编译器不需要执行任何操作......)
C17款 6.7.6.3 Function declarators (including prototypes)第 7 段说:

A declaration of a parameter as “array of type” shall be adjusted to “qualified pointer to type”, wherethe type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If thekeyword static also appears within the [ and ] of the array type derivation, then for each call tothe function, the value of the corresponding actual argument shall provide access to the first elementof an array with at least as many elements as specified by the size expression.


如果定义高于 ptr 的值必须至少提供对数组第一个元素的访问 1元素。因此很明显,该参数永远不能为空。
我在徘徊的是,使用不属于数组的 int 的地址调用这样的函数是否有效。例如。这是(根据上面 func 的定义)技术上有效还是未定义的行为:
int var = 5;
func(&var);
我知道这实际上永远不会成为问题,因为我所知道的编译器没有区分指向 int 数组成员的指针和指向局部 int 变量的指针。但是考虑到 c 中的一个指针(至少从标准的角度来看) can be如果标准中有某个部分,我会徘徊的不仅仅是一些具有特殊编译时类型的整数,这使得它有效。
我确实怀疑它实际上是无效的,如 6.5.6 Additive operators 部分第8段载有:

[...] If both the pointer operand and the result pointto elements of the same array object, or one past the last element of the array object, the evaluationshall not produce an overflow; otherwise, the behavior is undefined. [...]


对我来说,这听起来像是指向添加 1 的数组元素的任何指针。是一个有效的操作,而添加 1 是 UB指向指向常规变量的指针。这意味着,指向数组元素的指针和指向普通变量的指针之间确实存在差异,这将使 UB 上方的代码段...
栏目 6.5.6 Additive operators第7段载有:

For the purposes of these operators, a pointer to an object that is not an element of an array behavesthe same as a pointer to the first element of an array of length one with the type of the object as itselement type.


由于该段落以“为了这些运算符的目的”开头,我怀疑在其他上下文中可能存在差异?

tl;博士;
标准的某些部分是否指定了指向 T 类型的常规变量的指针之间没有区别?以及指向长度为 1 的数组元素的指针(类型为 T[1] 的数组)?

最佳答案

从表面上看,我认为你说的有道理。我们并没有真正传递指向数组第一个元素的指针。如果我们在真空中考虑标准,这可能是 UB。
除了您在 6.5.6 中引用的段落之外,标准中没有任何段落将单个对象等同于一个元素的数组。不应该有,因为这两件事是不同的。当出现在大多数表达式中时,数组(甚至一个元素)会隐式转换为指针。这显然不是大多数对象类型拥有的属性。static的定义[] 中的关键字提到传递的指针必须指向包含至少一定数量元素的数组的初始元素。你引用的措辞还有一个问题,那怎么办

int a[2];
func(a + 1);
显然,传递的指针不是指向数组的第一个元素。如果我们对 6.7.6.3p7 进行字面解释,那也是 UB。
static除了关键字,当函数接受指向对象的指针时,该对象是否是数组(任何大小)的成员或仅在一个上下文中无关紧要:指针算术。
在没有指针运算的情况下,当使用指针访问数组元素或独立对象时,行为没有明显差异。
我认为 6.7.6.3p7 背后的意图考虑了指针算法。因此,所提到的语义与尝试对传递给函数的指针进行指针运算密切相关。 static 1的使用只是自然而然地作为有用的习语出现,也许并不是一开始的意图。虽然规范性文本可能会稍作修正,但我认为其背后的意图是明确的。它并不意味着标准的未定义行为。

关于c - 将非数组变量的地址传递给声明为 `Type ptr[static 1]` 的函数参数是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62702208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com