C ++别名规则 [英] C++ aliasing rules
问题描述
只是想知道有人会为我确认几个别名规则。
我知道别名(即载入存储问题)导致以下类型的代码不是最佳的,因为我们不能假设 x,y,z
不重叠:
// case 1:
void plus(size_t n,double * x,double * y,double * z)
{
for(size_t i = 0; i!= n; ++ i)
z [i] = x [i] + y [i]
}
我知道有一个C关键字 __ restrict
提示编译器它不应该考虑重叠的情况,因此可能生成更好的代码:
// case 2:
void plus(size_t n,double * __ restrict x,double * __ restrict y,double * __ restrict z)
{//如上... }
但是别名如何使用C ++风格的代码,我们将处理传递的容器对象引用,而不是上面的类似C的例子,带有原始指针
例如,假设如果我们做了以下操作,会出现别名问题: / p>
// case 3:
void plus(std :: vector< double>& x,std :: vector< ; double>& y,std :: vector< double>& z)
{//类似于上面...}
并且为了移动到一个不太平凡的例子,如果容器中的底层数据类型不同,它是否有什么不同?在实现级别,大多数容器使用指针动态管理存储,因此我不清楚编译器如何确保以下不会出现别名:
// case 4:
void foo(std :: vector< mytype1>& x,std :: vector< mytype2>& y)
{// ,y ...}
我不想微观优化,
编辑:要清除一些术语,如下所示:
restrict
是C99关键字。在各种编译器中还有__ restrict
和__ restrict __
,但它们都做同样的事情。解决方案根据严格别名规则,不允许使用指向不同类型(
char *
和朋友)的指针对同一内存进行别名,因此案例4只能如果其中一个类型是char *
,则应用。
案例3虽然与案例1,因为引用被实现为我知道的所有编译器上的指针,虽然标准不要求,并且实现可以自由地提出别的东西。
Just wondering if someone would confirm a few aliasing rules for me.
I know that aliasing (i.e load-store issues) could cause the following type of code to be suboptimal, because we can't assume that
x, y, z
don't overlap:// case 1: void plus(size_t n, double *x, double *y, double *z) { for (size_t i = 0; i != n; ++i) z[i] = x[i] + y[i]; }
I know that there's a C keyword
__restrict
that hints to the compiler that it shouldn't consider the overlapping case, and hence potentially generate better code:// case 2: void plus(size_t n, double *__restrict x, double *__restrict y, double *__restrict z) { // as above... }
But how does aliasing work with C++ style code, where we would be dealing with container objects passed by reference, rather than the C-like examples above with raw pointers??
For instance, I'm assuming that there would be aliasing issues if we did the following:
// case 3: void plus(std::vector<double> &x, std::vector<double> &y, std::vector<double> &z) { // similar to above... }
And to move to a less trivial example, does it make any difference if the underlying data types in the containers are different?? At the implementation level most containers dynamically manage storage with pointers, so it's not clear to me how the compiler could ensure that the following doesn't alias:
// case 4: void foo(std::vector<mytype1> &x, std::vector<mytype2> &y) { // interwoven operations on x, y... }
I'm not trying to micro-optimise, but I'm wondering if it's currently better to pass restricted pointers to containers around, rather than references.
EDIT: To clear up some terminology, as pointed out:
restrict
is the C99 keyword. There's also__restrict
and__restrict__
in various compilers, but they all do the same thing.解决方案According to the strict-aliasing rule, you are not allowed to alias the same memory with pointers to different types (except
char*
and friends), so case 4 could only apply if one of the types was achar*
.Case 3 though isn't all that different from case 1, as references are implemented as pointers on all compilers I know, though the standard doesn't demand that and an implementation is free to come up with something else.
这篇关于C ++别名规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!