C ++别名规则

问题描述

| 只是想知道是否有人会为我确认一些别名规则。 我知道别名(即负载存储问题)可能会导致以下类型的代码不理想,因为我们不能假设ѭ0不会重叠:
// 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)
{ // as above... }
但是别名如何与C ++样式代码一起工作,在这里我们将处理通过引用传递的容器对象,而不是上面带有原始指针的类似C的示例? 例如,我假设如果执行以下操作,将会出现混叠问题:
// case 3:
void plus(std::vector<double> &x,std::vector<double> &y,std::vector<double> &z)
{ // similar to above... }
再举一个不那么琐碎的例子,如果容器中的基础数据类型不同,这有什么区别吗?在实现级别,大多数容器都使用指针动态管理存储,因此我不清楚编译器如何确保以下内容不具有别名:
// case 4:
void foo(std::vector<mytype1> &x,std::vector<mytype2> &y)
{ // interwoven operations on x,y... }
我没有尝试进行微优化,但是我想知道将受限制的指针传递给容器,而不是引用,目前是否更好。 编辑:指出来清除一些术语:
restrict
是C99关键字。在各种编译器中也有
__restrict
__restrict__
,但是它们都做相同的事情。     

解决方法

        根据严格的别名规则,不允许您使用指向不同类型的指针(same9ѭ和朋友除外)对同一内存进行别名别名,因此情况4仅在类型之一为
char*
的情况下适用。 情况3与情况1并没有什么不同,因为在我所知道的所有编译器上,引用都是作为指针实现的,尽管该标准并不要求这样做,并且实现可以自由提出其他建议。     ,        它根本不是C ++特有的。考虑一下此C99位:
struct vector {
    double* data;
    size_t n;
};

void
plus(struct vector* restrict x,struct vector* restrict y,struct vector* restrict z)
{
    // same deal as ever
}
在这里,
restrict
买给我们的东西很少:
x->data
y->data
z->data
都是
double*
,并且允许使用别名。即使使用限制,这也与情况1完全相同。 如果C ++中有一个
restrict
关键字(或使用扩展名),最好的选择可能是使用情况2中相同的ѭ19do来进行ѭ18And。实际上,现在可以使用C89风格的界面,不带ѭ6,但在幕后使用了关键字。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...