当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?
在GoingNative活动中,在第2天的交互式面板中,在9分钟时,Chandler Carruth说:
指针会产生锯齿问题.他们放慢你的二进制文件速度而不加速它们.
这是什么意思?这可以用(简单)示例来说明吗?
我正在阅读ISO/IEC 9899:TC2中第6.5段的第7段.
它通过以下方式宽恕对对象的左值访问:
一种聚合或联合类型,包括其成员中的上述类型之一(包括递归地,子聚合或包含联合的成员),
请参阅文档,了解"前面提到的"类型,但它们肯定包含对象的有效类型.
它的部分标注为:
此列表的目的是指定对象可能或可能没有别名的情况.
我读这是说(例如)以下定义很好:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
unsigned int x;
} s;
int main(void){
unsigned int array[3] = {73,74,75};
s* sp=(s*)&array;
sp->x=80;
printf("%d\n",array[0]);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
该程序应输出80.
我不是在提倡这是一个好的(或非常有用的)想法,并且承认我在某种程度上解释它是因为我无法想到其他意味着什么并且不能相信它是一个毫无意义的句子!
也就是说,我看不出有理由禁止它.我们所知道的是该位置的对齐和内存内容是否兼容,sp->x
为什么不呢?
它似乎甚至可以说,如果我double y;
在结构的末尾添加(说)a ,我仍然可以array[0]
通过sp->x
这种方式访问它.
但是,即使数组大于sizeof(s)
任何访问尝试sp->y
都是'所有下注'未定义的行为.
可能我礼貌地要求人们说出那句话宽恕而不是进入一个扁平的旋转喊"严格混淆UB严格别名UB"似乎经常是这些事情的方式.
在 C 中有一个restrict
关键字告诉编译器在函数的指针参数之间没有别名,允许它以这种方式执行一些否则将不允许的优化。例如:
void add(int* restrict ptrA,
int* restrict ptrB,
int* restrict val)
{
*ptrA += *val;
*ptrB += *val;
}
Run Code Online (Sandbox Code Playgroud)
现在函数体中的指令可以并行执行,因为val
和 某些ptr
参数之间没有别名。在 C++ 中没有restrict
关键字。
restrict
C 中的语义?例如MSVC、g++、clang++和Intel C++ compiler。restrict
在未来的 C++ 标准中是否有任何计划要标准化的关键字?