在C中将数组的内容转换为算术类型

use*_*208 0 c pointers casting access-violation dereference

我将面对奇怪的行为,将数组中的单个项目(或更多甚至解除引用)转换为单个算术类型.

下面是一个简化的测试用例:

void test1()
{
    unsigned char test[10] = {0};
    unsigned long i=0xffffffff;

    *((unsigned long *)(&test[3])) = i;


    int it;

    for ( it = 0 ; it < 10 ; it++ )

    {
        printf("%02x ", test[it]);

    }
}
void test2()
{
    unsigned char test[10] = {0};
    unsigned char test2[10] = {0};
    test[2]=0xFF;
    test[3]=0xFF;

    *((unsigned short *)(&test2[1])) = *((unsigned short *)(&test[2]));


    int it;

    for ( it = 0 ; it < 10 ; it++ )

    {
        printf("%02x ", test2[it]);

    }
}
Run Code Online (Sandbox Code Playgroud)

详细说明主要是这个表达式:

    *((unsigned short *)(&test2[1]))
Run Code Online (Sandbox Code Playgroud)

我在其他一些平台(主要是PIC24等嵌入式平台)上遇到访问冲突.

所以我的问题是:这个C符合吗?我在C标准中找不到任何东西,但也许我只是盲目的.

你是否知道在没有这种操作的情况下执行此操作的任何替代方法(循环字节到字节的复制/展开等并不意味着!)并且我不需要知道平台的当前字节顺序?

谢谢!

oua*_*uah 5

 *((unsigned short *)(&test2[1]))
Run Code Online (Sandbox Code Playgroud)

这是未定义的行为,您违反了对齐和别名规则.不要这样做.

您的test2对象是一个数组,unsigned char通过转换,您将其元素作为unsigned short对象访问.无法保证unsigned char对齐要求与unsigned short对齐要求相同.

在C标准中,您可以在6.3.2.3p7(C99)中找到有关对齐的信息,在6.5p7中可以找到有关对齐规则的信息.

一个好的经验法则是在=操作员左侧存在铸件时始终保持警惕.