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

TS

如所提到的在这里在这里在这里的函数(在C99或更新版本)以这种方式定义

void func(int ptr[static 1]){
    //do something with ptr, knowing that ptr != NULL
}

具有一个ptr指向int类型指针的参数(),并且编译器可以假定该函数永远不会以null为参数调用。(例如,编译器可以优化空指针检查,或者警告是否使用nullpointer调用了func-是的,我知道,编译器不需要执行任何操作……)

C17第6.7.6.3功能声明符(包括原型)第7段规定:

参数声明为“类型数组”应调整为“类型的合格指针”,其中类型限定符(如果有)是在数组类型派生的[和]中指定的那些。如果关键字static也出现在数组类型派生的[和]中,则对于函数的每次调用,相应实际参数的值应提供对数组第一个元素的访问,该元素至少具有指定数量的元素通过大小表达式。

在上述定义的情况下,必须使用的值ptr提供对至少具有元素的数组的第一个元素的访问1因此,很明显参数不能为空。

我正在徘徊的是,使用不属于数组一部分的int地址调用这样的函数是否有效。例如(从func上面的定义来看)这在技术上是有效的还是未定义的行为:

int var = 5;
func(&var); 

我知道这几乎不会成为问题,因为我所知没有编译器会区分指向int数组成员的指针和指向局部int变量的指针。但是考虑到c中的指针(至少从标准的角度来看)可以不仅仅是具有特殊编译时间类型的某个整数,所以如果标准中有某些部分,我徘徊了,这使它有效。

我确实怀疑它实际上是无效的,因为第6.5.6节“加法运算符”第8段包含:

[...]如果指针操作数和结果都指向同一数组对象的元素,或者指向数组对象的最后一个元素之后,则求值不应产生溢出;否则,行为是不确定的。[...]

对我来说,听起来好像任何指向数组元素添加的指针1都是有效的操作,而添加1到指向常规变量的指针将是UB 这意味着,指向数组元素的指针与指向普通变量的指针之间确实存在差异,这会使摘要高于UB ...

6.5.6节“加法运算符”第7段包含:

就这些运算符而言,指向不是数组元素的对象的指针的行为与指向长度为1且对象类型为其元素类型的数组的第一个元素的指针的行为相同。

由于该段以“出于这些运营商的目的”开头,我怀疑在其他情况下会有所不同吗?


tl; dr;

标准中是否有某些部分规定,指向类型为正则变量的T指针与长度为1的数组(类型为array)的元素的指针之间没有区别T[1]

讲故事的人-Unslander Monica

从表面上看,我认为你有一点。我们并没有真正将指针传递给数组的第一个元素。如果我们在真空中考虑标准,则可能是UB。

除了您在6.5.6中引用的段落外,标准中没有段落将单个对象等同于一个元素的数组。而且不应该这样,因为两者是不同的。当一个数组(甚至包含一个元素)出现在大多数表达式中时,都会隐式转换为指针。显然,这不是大多数对象类型拥有的属性。

static关键字的定义[]提到要传递的指针必须指向至少包含一定数量元素的数组的初始元素。您引用的措词还有另一个问题,那

int a[2];
func(a + 1);

显然,传递的指针不是数组第一个元素。如果我们对6.7.6.3p7进行字面解释,也就是UB。

放开static关键字,当函数接受指向对象的指针时,对象是否是数组(任何大小)的成员,仅在以下一种情况下很重要:指针算术。

在没有指针算术的情况下,使用指针访问数组的元素或独立对象时,行为没有明显区别。

我认为6.7.6.3p7背后的意图考虑了指针算法。因此,所提到的语义与尝试对传递给函数的指针进行指针算术相结合。

static 1简单地自然而然地使用有用的成语,也许不是从一开始就打算这样做。虽然规范性文本可能会稍作修改,但我认为其意图很明确。这并不意味着是标准定义的行为。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将多维数组传递给** ptr函数

将常量文字数组传递给函数而不将其声明为变量

将非算术类型作为参数传递给cmath函数是否有效?

将声明为“自动”的 std::shared_ptr<Derived> 传递给 std::shared_ptr<Base>&

通过引用将变量传递给函数是否比使函数返回变量更有效?

将复合文字传递给函数是否有效?

C ++:将诸如unique_ptr :: get()之类的参数传递给函数是否安全?

将std :: weak_ptr传递给函数是否有用?

使用已使用 new X() 创建的变量将 std::unique_ptr 传递给函数

如何调用传递的函数(将函数ptr作为参数传递给函数)

使用shared_ptr将原始指针传递给函数

将 shared_ptr 传递给函数 - 需要澄清

将shared_ptr传递给std :: function(成员函数)

如何将std :: unique_ptr传递给函数

将const shared_ptr <T>&传递给shared_ptr <T>作为参数

包含指针的结构上的指针:数组命名法有效但无效 (ptr + 1)。为什么?

将unique_ptr <Derived>&传递给接受unique_ptr <Base>&的函数

将std :: shared_ptr <T>传递给采用std :: shared_ptr <const T>的函数?

通过type(c_ptr)虚拟变量传递外部函数和自定义数据类型

是否可以将vector <shared_ptr <T >>传递给const vector <shared_ptr <const T >>&参数?

在FFI中使用ptr :: NonNull是否有效?

如何将参数类型数组传递给Type []?

在声明为返回unique_ptr <Base>的函数中返回unique_ptr <Derived>

如何将unique_ptr参数传递给构造函数或函数?

C ++中的有效循环缓冲区,将传递给C样式数组函数参数

将多个参数传递给函数的最有效方法?

如何有效地将巨大的参数传递给函数?

如何将NULL或nullptr传递给接收unique_ptr参数的函数?

将引用参数传递给采用 unique_ptr 的通用引用的函数