我可以在不中断代码的情况下删除此警告吗?

Can I remove this warning without break code?

本文关键字:删除 警告 情况下 中断 代码 我可以      更新时间:2023-10-16
    unsigned char data[] =
    {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0
    };
    *((int*) &data[1]) = 0x00256;

this给出警告(见下文)我可以在不破坏代码的情况下删除它吗?通过break,也就是说,如果我转换到unsigned char*,我将复制比我正在寻找的更少的字节(不是所有32位整数),对吧?

警告:从'unsigned char *'转换为'int *'需要增加[-Wcast-align]

这里有几件事。

1。指针复制。

如果p是*int类型,那么*p =将复制sizeof(int)(4)个字节。同样,*char类型的指针将复制1个字节。您使用的字面值是0x00000256的缩写形式,这4个字节将被复制到从&data[1]开始的内存位置。

2。字节顺序

几乎可以肯定的是,这个操作将赋值如下(这是否与你期望的相反?):因为现在使用的几乎所有东西都是小端序的。

 data[1] = 0x56
 data[2] = 0x2
 data[3] = 0x0
 data[4] = 0x0

3。对齐

考虑以下c++程序(用于alignof操作符)

#include <iostream>
using namespace std;
int main(int argc,char *argv[])
{
   char a[4];
   int b[1];
   cout << "char alignment = " << alignof(char) << endl;
   cout << "int alignment = " << alignof(int) << endl;
   cout << "a alignment = " << alignof(a) << endl;
   cout << "b alignment = " << alignof(b) << endl;
}

生产

char alignment = 1
int alignment = 4
a alignment = 1
b alignment = 4

来自c++规范(第3.11节)

对象类型有对齐要求(3.9.1,3.9.2),这对该类型对象可以分配的地址进行了限制。对齐是一个实现定义的整数值,表示一个给定对象可以被分配的连续地址之间的字节数。

这意味着访问/存储类型取决于它的对齐,它是由实现来决定当它被违反时会发生什么。

对于现代英特尔硬件(参见这里,这里和这里),您的操作可能有效。但是访问不对齐的数据并不能保证在Intel上是原子的,因此不鼓励这样做。然而,在其他(Sparc)硬件上,当试图存储该值时,您很可能会遇到异常(总线错误),程序将崩溃。