C ++别名规则 [英] C++ aliasing rules

查看:173
本文介绍了C ++别名规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是想知道有人会为我确认几个别名规则。



我知道别名(即载入存储问题)导致以下类型的代码不是最佳的,因为我们不能假设 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 a char*.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆