Pra*_*rav 5 c pointers type-conversion type-safety
以下转换是否安全?
int b[10][10];
char *x;
int a[]={0,1,2,3,4,5,6,7,8,9};
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
b[i][j]=a[i];
for(x=(char *)&b[0];x<=(char *)&b[9][9];x+=sizeof(a+1)) // Problem lies here!
printf("%d\n",*x);
Run Code Online (Sandbox Code Playgroud)
我不认为for循环中的上述转换是安全的(我认为它取决于平台).如果我错了,请纠正我.我很惊讶因为即使使用-Wall -pedanticgcc中的选项进行编译,代码也会编译而不会发出任何警告.
这一切都有可能是合法的,只有一个原因:2D int数组对象被重新解释为一个char对象数组.虽然在一般情况下,内存重新解释会导致未定义的行为,但语言规范明确允许对任何类型的对象进行"[signed/unsigned] char数组"重新解释.
但是,仍存在一个正式的安全问题.该语言不保证任何位模式都是char类型的有效值.char如果遇到陷阱表示,您尝试通过类型读取重新解释的内存理论上会导致未定义的行为char.为了安全起见,您必须使用unsigned char类型,这是唯一没有陷阱表示的类型.当然,具有陷阱的平台char可以被安全地称为"异国情调".
同时,你sizeof(a + 1)似乎没有任何意义.a + 1是一种int *类型的表达.x在这种情况下,为什么你想要使用指针大小增加你的值我不清楚.你想要达到什么目的?
至于没有警告......我不希望编译器在这里发出任何警告.海湾合作委员会经常警告类型惩罚(又称记忆重新解释),但由于char明确允许重新解释(如上所述),这里没有任何警告.此外,显式强制转换通常倾向于抑制任何警告,因为它们是告诉编译器您确实想要执行某些操作的一种方式,无论它可能有多么错误和/或危险.