受限指针问题
我对有关受限指针的规则有点困惑。也许有人可以帮助我。
如下定义嵌套受限指针是否合法:
int* 限制 a; int* 限制 b; a = malloc(sizeof(int)); // b = a; <-- 这里的赋值是非法的,需要在子块中进行 // *b = 兰特(); 同时(1) { b = a; // 这合法吗?假设 'b' 在 while() 块之外没有被修改 *b = 兰特(); }
按如下方式派生受限指针值是否合法:
int* 限制 c; int* 限制 d; c = malloc(sizeof(int*)*101); d = c; for(int i = 0; i < 100; i++) { *d = 我; d++; } c = d; // c 现在设置为 101 元素,假设 d 未被访问,这是否合法? *c = 兰特();
谢谢! 安德鲁
I'm a little confused about the rules regarding restricted pointers. Maybe someone out there can help me out.
Is it legal to define nested restricted pointers as follows:
int* restrict a; int* restrict b; a = malloc(sizeof(int)); // b = a; <-- assignment here is illegal, needs to happen in child block // *b = rand(); while(1) { b = a; // Is this legal? Assuming 'b' is not modified outside the while() block *b = rand(); }
Is it legal to derive a restricted pointer value as follows:
int* restrict c; int* restrict d; c = malloc(sizeof(int*)*101); d = c; for(int i = 0; i < 100; i++) { *d = i; d++; } c = d; // c is now set to the 101 element, is this legal assuming d isn't accessed? *c = rand();
Thanks!
Andrew
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
作为参考,这里是
restrict
限定符的相当复杂的定义(来自 C99 6.7.3.1“Restrict 的正式定义”):我对上述内容的阅读意味着,在你的第一个问题中,即使在“子”块内,
a
也不能分配给b
- 结果是未定义的。如果b
在该“子块”中声明,则可以进行此类分配,但由于b
是在与a
相同的范围内声明的,无法进行分配。对于问题 2,
c
和d
之间的赋值也会导致未定义的行为(在这两种情况下)。标准中的相关部分(对于两个问题)是:
由于受限指针与同一块关联,因此块 B2 不可能在 B 执行之前开始,也不可能在赋值之前结束 B2(因为 B 和 B2 是同一块)。
该标准给出了一个例子,使这一点非常清楚(我认为 -
restrict
定义的 4 个短段落的清晰度与 C++ 的名称解析规则相当):For reference, here's the
restrict
qualifier's rather convoluted definition (from C99 6.7.3.1 "Formal definition of restrict"):My reading of the above means that in your first question,
a
cannot be assigned tob
, even inside a "child" block - the result is undefined. Such an assignment could be made ifb
were declared in that 'sub-block', but sinceb
is declared at the same scope asa
, the assignment cannot be made.For question 2, the assignments between
c
andd
also result in undefined behavior (in both cases).The relevant bit from the standard (for both questions) is:
Since the restricted pointers are associated with the same block, it's not possible for block B2 to begin before the execution of B, or for B2 to end prior to the assignment (since B and B2 are the same block).
The standard gives an example that makes this pretty clear (I think - the clarity of the
restrict
definition's 4 short paragraphs is on par with C++'s name resolution rules):restrict
类型限定符向编译器发出指示,如果restrict
限定指针所寻址的内存被修改,则其他指针将不会被修改。访问相同的内存。编译器可能会选择优化涉及restrict
限定指针的代码,否则可能会导致不正确的行为。 程序员有责任确保限制限定指针按其预期用途使用。否则,可能会导致未定义的行为。 (link)正如您从上面的描述中看到的,您的两个赋值都是非法的,这可能在某些编译器生成的可执行文件中有效,但在其他编译器中会中断。不要指望编译器本身会发出错误或警告,因为
restrict
只是提供了执行某些优化的机会,它可以选择不执行,就像volatile
的情况一样>。The
restrict
type qualifier is an indication to the compiler that, if the memory addressed by therestrict
-qualified pointer is modified, no other pointer will access that same memory. The compiler may choose to optimize code involvingrestrict
-qualified pointers in a way that might otherwise result in incorrect behavior. It is the responsibility of the programmer to ensure that restrict-qualified pointers are used as they were intended to be used. Otherwise, undefined behavior may result. (link)As you can see from the above description, both your assignments are illegal, that may work in executables produced by some compilers but break in others. Don't expect the compiler itself to emit errors or warnings as
restrict
just gives an opportunity to perform certain optimization, which it can choose not to perform, like in the case ofvolatile
.