C++ 为什么不强制执行_限制_修改器?

C++ 为什么不强制执行_限制_修改器?,c++,pass-by-reference,restrict-qualifier,C++,Pass By Reference,Restrict Qualifier,如果一个函数参数被注释为const int&x,并且我试图在函数体中执行x++,那么修改只读引用时会出现编译时错误。但是如果我像这样使用\uuuuu restrict\uuuu修饰符: void foo(int & __restrict__ a, int & __restrict__ b) { if (a == 1) b = 2; if (a == 2) b = 3; } int main() { int x = 1;

如果一个函数参数被注释为
const int&x
,并且我试图在函数体中执行
x++
,那么修改只读引用时会出现编译时错误。但是如果我像这样使用
\uuuuu restrict\uuuu
修饰符:

void foo(int & __restrict__ a, int & __restrict__ b) {
    if (a == 1)
        b = 2;
    if (a == 2)
        b = 3;
}

int main() {
    int x = 1;
    foo(x, x); // should be illegal?
    cout << x;
}
void foo(int&\uuu restrict\uuuuuua,int&\uu restrict\uuub){
如果(a==1)
b=2;
如果(a==2)
b=3;
}
int main(){
int x=1;
foo(x,x);//应该是非法的吗?

cout在非常普遍的情况下,不可能在编译时对其进行诊断。正如一个简单的反例,请考虑:

 void foo(int* __restrict__ a, int * __restrict__ b);

 int x;
 int y;
 std::cin >> x >> y;
 int* a = (x%2) ? &x : &y;
 int* b = (y%2) ? &x : &y;
 foo(a,b);

编译器无法知道
a
b
是否会指向相同的
int
。事实上,如果编译器能够进行这样的分析,就不需要
\uuuuuuuuu限制\uuuuu
限定符,因为这样编译器就可以自己判断是否使用两个指针访问相同的内存。

在同一代中一般情况下,不可能在编译时对其进行诊断。正如一个简单的反例,请考虑:

 void foo(int* __restrict__ a, int * __restrict__ b);

 int x;
 int y;
 std::cin >> x >> y;
 int* a = (x%2) ? &x : &y;
 int* b = (y%2) ? &x : &y;
 foo(a,b);

编译器无法知道
a
b
是否会指向相同的
int
。事实上,如果编译器能够进行这样的分析,就不需要
\uuuuuuuuu限制\uuuuu
限定符,因为这样编译器就可以自己判断两个指针是否用于访问同一内存。

不是这样的通常易于检测
限制
违规。假设您有一个函数

void bar(int* p1, int* p2) {
    foo(*p1, *p2);
}
在这种情况下,编译器应该做什么

在某些情况下(如在您的示例中),
restrict
冲突可以被检测到,并且被某些编译器检测到。例如,带有
-forvertrict
的GCC会产生警告:

警告:传递参数1以限制参数2的限定参数别名

合同通用条款(GCC)内容如下:

当一个对象引用的代码< > < /Cult> -限定参数(或者,在C++中,一个<代码>限制> <代码> -限定参数)被另一个参数混淆,或者当这些对象之间的副本重叠时,


您可以使用with
-Werror=restrict
选项将此警告转化为错误。

一般来说,检测
restrict
违规并不容易。假设您有一个函数

void bar(int* p1, int* p2) {
    foo(*p1, *p2);
}
在这种情况下,编译器应该做什么

在某些情况下(如在您的示例中),
restrict
冲突可以被检测到,并且被某些编译器检测到。例如,带有
-forvertrict
的GCC会产生警告:

警告:传递参数1以限制参数2的限定参数别名

合同通用条款(GCC)内容如下:

当一个对象引用的代码< > < /Cult> -限定参数(或者,在C++中,一个<代码>限制> <代码> -限定参数)被另一个参数混淆,或者当这些对象之间的副本重叠时,


您可以使用with
-Werror=restrict
选项将此警告转化为错误。

您正在向后查看
\uuuu restrict\uuuu

\uuuuu restrict\uuuuu
是一个实现扩展,程序员可以使用它来表示意图,以最大限度地提高生成的代码质量和性能(“优化”)

这不是一个检查,也不是对程序的附加约束

它不是类型系统的一部分,因此它不是函数类型的一部分,因此不能在调用站点强制执行(通常)

它就像其他一些扩展(如
\uu内置的\u不可访问的
),用来告诉编译器一些事情

在本例中,您告诉它“我不是通过任何其他指针引用指针对象”

你不是在问“请阻止我通过任何其他指针引用指针对象”

C和C++编译器已经执行了强大的“别名”检查。在这里,“代码”>限制符> /Cord>关键字是一种方式,告诉你“我确信这一点”,在自动混淆检测无法工作的情况下(例如,翻译单位边界)。。由于自动别名检测无法工作,因此无法强制执行

\uuuuuuuuuuuuuuuuuuuuuuuuuu


而且,即使它可能是,那也与修饰符的用途相反。

您正在向后查看
\uuuuuuuuuuuuuuuuuuuuuuuu

\uuuuu restrict\uuuuu
是一个实现扩展,程序员可以使用它来表示意图,以最大限度地提高生成的代码质量和性能(“优化”)

这不是一个检查,也不是对程序的附加约束

它不是类型系统的一部分,因此它不是函数类型的一部分,因此不能在调用站点强制执行(通常)

它就像其他一些扩展(如
\uu内置的\u不可访问的
),用来告诉编译器一些事情

在本例中,您告诉它“我不是通过任何其他指针引用指针对象”

你不是在问“请阻止我通过任何其他指针引用指针对象”

C和C++编译器已经执行了强大的“别名”检查。在这里,“代码”>限制符> /Cord>关键字是一种方式,告诉你“我确信这一点”,在自动混淆检测无法工作的情况下(例如,翻译单位边界)。。由于自动别名检测无法工作,因此无法强制执行

\uuuuuuuuuuuuuuuuuuuuuuuuuu


,即使它可能是,也将是修改器的目的的相反。< /P>它是未定义的行为。我只是不确定是否可以发布答案,因为我很难找到适当的引用,C++注释C++没有做任何事情,因为它是一个实现扩展。Havior。我只是不确定,可以发布一个答案,因为我有困难找到合适的引用C++注释,C++没有做任何事情,与<代码>