是对以下转换安全?

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);

我不认为在for环上面的转换是安全的(我认为是依赖于平台)。如果我错了请纠正我。我很惊讶,因为在代码编译,而不使用在GCC的-Wall -pedantic选项编译,即使给予任何警告。

有帮助吗?

解决方案

这整个事情具有作为合法的一个且仅一个原因的机会:在2D阵列int对象被重新解释为char对象的数组。而在一般情况下,存储器的重新解释导致未定义的行为,语言规范明确允许重新解释“[符号/无符号] char数组”为任何类型的对象。

然而,一个正式的安全问题依然存在。语言不保证任何位模式是char类型的有效价值。您试图通读char类型内存的再认识理论上可以导致不确定的行为,如果它遇到陷阱表示为char。为了安全起见在这里你必须使用unsigned char类型,这是没有陷阱表示唯一的类型。当然,随着捕集char的平台可以安全地被称为“外来的”。

同时,您sizeof(a + 1)似乎没有任何意义。 a + 1int *类型的表达式。为什么你要使用的指针大小在这种情况下,以增加你的x值我不清楚。什么是你想达到什么目的?

至于没有警告......我不希望编译器在这里发出任何警告。 GCC经常发出警告类型双关(又名记忆重新解释),但由于char重新解释明确允许(正如我上面说的),这里有没有警告。此外,显式转换通常倾向于抑制任何警告,因为他们告诉编译器的方式,你真正想要做一些事情,无论多么错误和/或危险的可能是。

其他提示

任何指针类型为char *的铸造明确由C语言允许的。所以大多数的,这是好的。

for(x=(char *)&b[0]; x <= (char *)&b[9][9]; x += sizeof(a+1))  

的第一部分是细x = (char*)&b[0];建立一个char指向数组的开始。该试验也是细x <= (char *)&b[9][9]将是只要数组内X点真。

x += sizeof(a+1)是还不确定部分。在大多数32位CPU架构的sizeof(INT *)刚刚的发生的是一样的sizeof(int)的,所以这段代码可能会工作的,但只能是偶然的

我知道是什么用意是x += sizeof(a[0])x += sizeof(b[0]),但由于代码实际上做了什么的目的,没有人注意到这个错误。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top