在C中使用限制指针时,可以使用其初始标识符更改变量吗?
-
30-09-2019 - |
题
使用时 restrict
C中的指针,可以使用其初始变量更改该变量 标识符?例如:
int foo = 0;
int * restrict fooPtr = &foo;
++(*fooPtr); // Part 1: foo is 1 (OK)
++foo; // Part 2: foo is 2 (Is this OK?)
int * fooPtr2 = &foo;
++(*fooPtr2); // Part 3: foo is 3 (BAD: You shouldn't access via a second pointer)
...我改变了价值 foo 通过 foo 之后 restrict
fooptr 被创建了。
第1部分 对我来说还可以。我很困惑 第2部分. 。据我了解 restrict
, 第3部分 是不好的(编译器允许它,但其行为不确定,这取决于程序员不这样做)。
解决方案
不,第2部分不行。
标准的特定部分为6.7.3.1/4。本节非常密集,需要进行一些重新阅读,但是P是一个限制指针,X是用于访问的某个对象,并且已修改。因此,在您的示例中P是 fooPtr
x是 foo
. 。然后:
用于访问X值的所有其他LVALUE也应基于P的地址。
“基于”在上一段中定义了,并总结一下lvalue foo
做 不是 根据限制指针P有其地址 foo
通过自己的名字。
第3部分由于完全相同的原因是不可行的。 *fooPtr2
也不基于P,但也用于访问X。
我说“不正常” - 确切地说,1+2的组合挑衅不确定的行为,1+3的组合也是如此。只要您实际上没有通过限制指针访问对象,就没有限制“踢”的定义。如果您愿意,可以删除第1部分,保留未使用的限制指针,然后2和3可以。
其他提示
是的,“第3部分”是不确定的行为。从C99规格(6.7.3,第7段):
通过限制性的指针访问的对象与该指针具有特殊关联。该关联在下面的6.7.3.1中定义,要求直接或间接地使用该对象使用该特定指针的值。
我会说#2很糟糕。例如,编译器可能会通过将 *fooptr的值加载到寄存器中来优化,然后稍后再将寄存器值写回FOO,以后 - ++ foo之后,以便丢失++ foo。
假设您的问题的所有部分都发生在同一块中,则无法访问的值 foo
直接(第2部分)或通过另一个指针(第3部分)访问它:
- 6.7.3.1正式的限制定义
用于访问X值的所有其他LVALUE也应基于P的地址。
正式定义 restrict
很难遵循(至少对我来说是),但是从标准来看,以下正式描述也不太正式总结得很好(至少在这种情况下):
通过限制性指针访问的对象与该指针具有特殊关联。该关联在下面的6.7.3.1中定义,要求直接或间接地使用该对象使用该特定指针的值。