可以使用任何数据类型吗?[英] Can a char array be used with any data type?

本文是小编为大家收集整理的关于可以使用任何数据类型吗?的处理方法,想解了可以使用任何数据类型吗?的问题怎么解决?可以使用任何数据类型吗?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

malloc()函数返回类型void*的指针.它根据size_t值作为参数分配给字节的内存.得到的分配是原始字节,可以与C中的任何数据类型一起使用(无铸造).

可以在返回void *的函数中声明的类型char的数组,与所得到的任何数据类型一起使用,如所得到的malloc?

例如,

#include <stdio.h>

void *Stat_Mem();

int main(void)
{
    //size : 10 * sizeof(int)
    int buf[] = { 1,2,3,4,5,6,7,8,9,10 };

    int *p = Stat_Mem();

    memcpy(p, buf, sizeof(buf));

    for (int n = 0; n < 10; n++) {
        printf("%d ", p[n]);
    }
    putchar('\n');

    return 0;
}

void *Stat_Mem()
{
    static char Array[128];
    return Array;
}

推荐答案

静态对象的声明类型Array是char.此对象的有效类型是它已声明类型.无法改变静态对象的有效类型,因此对于程序的其余部分,有效类型的Array是char.

如果您尝试使用与此列表中不兼容的类型的对象的值 1 ,则该行为是未定义的.

代码尝试使用类型int访问Array的存储值.此类型与类型char不兼容,并且不在例外列表中,因此使用int指针p:

读取阵列时,行为是未定义的
printf("%d ", p[n]);

1 (引用来自:ISO:IEC 9899:201x 6.5表达式7)
一个对象应仅通过levalue访问其存储的值 具有以下类型之一的表达式:
- 一种 兼容物体的有效类型,
- 合格 版本的类型与对象的有效类型兼容,
- 一种类型的类型,它是对应的签名或无符号类型 有效类型的物体,
- 一种签名或无签名的类型 类型对应于有效类型的合格版本 对象,
- 包含其中一个的聚合或联合类型 其成员之间的上述类型(包括递归,a 子发声或包含联盟的成员),或


- 字符类型.

其他推荐答案

否您无法为任意类型使用任意字节数组,因为可能的对齐问题.该标准在6.3.2.3转换/指针(强调矿井):

指向对象或不完整类型的指针可能会转换为指针转换为其他 对象或不完整类型. 如果生成的指针未正确对齐 指向类型,行为是未定义的.否则,当再次转换后, 结果应与原始指针相比.

作为最小的对齐要求,您无法确保您的Char数组将正确对齐任何其他类型.这就是为什么Malloc保证由malloc获得的缓冲区(即使是void *)具有最大可能的对准要求,以便能够接受任何其他类型.


我认为

union {
    char buf[128];
    long long i;
    void * p;
    long double f;
};

应该对任何类型正确对齐,因为它与最大的基本类型兼容(如6.2.5类型中所定义).我很确定它将适用于所有常见实现(GCC,Clang,MSVC,......),但遗憾的是,我找不到标准允许它的任何确认.基本上是因为6.5表达式中定义的严格的混叠规则§7:

一个对象仅由具有其中一个的偏僻料表达式访问其存储值 以下类型:

  • 一种与物体有效类型兼容的类型,
  • 与对象的有效类型兼容的类型的合格版本,
  • 作为与有效类型相对应的签名或无符号类型的类型 对象,
  • 作为与合格版本相对应的签名或无符号类型的类型 有效类型的物体,
  • 包括其中一个上述类型之一的聚合或联合类型 会员(包括,递归,子缩略或包含的联盟的成员),或
  • 一个字符类型.

所以imho没有便携式和标准符合方式来构建自定义分配器不使用malloc.

其他推荐答案

如果读取C89标准的基本原理,则存在类型规则的唯一原因是避免需要编译器制作"最坏情况的锯齿化假设".给定的例子是:

    int a;
    void f( double * b )
    {
        a = 1;
        *b = 2.0;
        g(a);
    }

如果程序在包含对齐的union中创建一个"char"阵列,其对齐将适合任何类型的内容,则涉及其地址,并且永远不会通过生成的指针访问该结构的存储,应该没有原因别名规则应该造成任何困难.

值得注意的是,标准的作者认识到,实施可以同时兼容但未毫无用处;参见C89 2.2.4.1:

的理由

虽然缺乏的实施可能会涉及符合这一要求的程序,但仍然成功毫无用处,委员会认为这种聪明才智可能需要更多的工作,而不是制造有用的东西.委员会的意义于,实施者不应将翻译限制解释为硬线参数的值,而是作为一组将判断实施的标准.

虽然该特定声明是关于实施限制,将C89解释为甚至远程兼容的唯一方法,甚至与之前的C方言兼容,这也将其视为更广泛的应用:标准没有尝试彻底指定程序应该能做的所有内容,而是依赖于编译器作家的行使一些常识.

使用字符型阵列作为任何类型的备用存储,假设一个确保对准问题是关注的,不应造成非斜视写入编译器的任何问题.该标准并没有授权编译器作家允许这样的事情,因为他们没有理由期望他们以其他方式做出这样做.不幸的是,他们未能预见到21世纪的道路.

本文地址:https://www.itbaoku.cn/post/359229.html