【问题标题】:Can I remove this warning without break code?我可以在不使用中断代码的情况下删除此警告吗?
【发布时间】:2014-04-30 11:20:43
【问题描述】:
    unsigned char data[] =
    {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0
    };

    *((int*) &data[1]) = 0x00256;

这给出了警告(见下文)我可以删除这个没有破坏代码的东西吗?通过中断,即,如果我转换为unsigned char*,我实际上将复制比我正在寻找的更少的字节(不是所有 32 位整数),对吧?

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

【问题讨论】:

  • 如果您认为该警告不重要,那么您可能以前从未编写过 SPARC。并且您将文字分配给 int 取消引用。不管你喜不喜欢,你都在移动sizeof(int) bytes somewhere
  • 但我真的很想移动sizeof(int)。我想通过代码具体删除这个警告,但我认为这是不可能的

标签: c++ memory-management alignment clang


【解决方案1】:

这里发生了一些事情。

1。指针复制。

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

2。字节序

几乎可以肯定,此操作将分配以下内容(这是否与您的预期相反?):因为现在使用的几乎所有内容都是 little endian

 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 硬件,请参阅 hereherehere,您的操作可能会成功。但是访问未对齐的数据在英特尔上并不保证是原子的,并且不鼓励这样做。但是,在其他 (Sparc) 硬件上,您在尝试存储该值时很可能会遇到异常(总线错误),并且程序将崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多