【问题标题】:Explanation of "effective type"?“有效类型”的解释?
【发布时间】:2019-06-20 16:52:15
【问题描述】:

我正在阅读 C 规范,该规范在 6.5 Expressions 中声明

访问其存储值的对象的有效类型是对象的声明类型(如果有)。如果通过具有非字符类型类型的左值将值存储到没有声明类型的对象中,则左值的类型将成为该访问的对象的有效类型以及不修改该类型的后续访问储值。

谁能解释一下这是什么意思?我有一种模糊的感觉,它与指针和malloc() 有关,但在没有律师帮助的情况下,我只能做到这一点......

根据答案更新:我可以安全地执行此操作吗?

struct point {
    int x;
    int y;
};

int main() {
    int *x = malloc(1000);
    *x = 10;
    printf("%d\n", *x);

    struct point *p = x;
    p->x = 5;
    p->y = 10;
    printf("%d %d\n", p->x, p->y);
}

我收到警告,但它适用于我的情况。能保证有效吗?

【问题讨论】:

  • 其他人认为语言律师标签在这里可能是合适的,因为它直接询问标准的引用?
  • 您能否编辑/评论以表明这是来自标准的哪个部分?
  • @CoffeeTableEspresso:已编辑
  • @CoffeeTableEspresso 6.5.17

标签: c


【解决方案1】:

当你声明一个给定类型的变量时,它引用该类型的底层对象,所以对象的有效类型是关联变量的类型。

malloc 发挥作用时,事情变得有点模糊。从malloc 返回的内存没有有效类型。例如:

int *x = malloc(sizeof(int));

假设 int 的大小为 4 字节,x 现在指向没有有效类型的 4 字节内存。此内存在分配给时获得有效类型:

*x = 123;

现在这些字节的有效类型为int

在您的示例中,您分配了 1000 个字节,最初这些字节没有有效类型。

*x = 10;

这使得第一个 sizeof(int) 字节成为 int 类型的对象。

struct point *p = x;

这个应该有一个演员表,但最后没关系,因为struct point的第一个成员的类型为int,并且指向结构的指针指向它的第一个成员。

p->x = 5;

因此这是安全的,因为&p->x 指向类型为int 的对象,它与左值p->x 的类型匹配。

p->y = 10;

这也是安全的,因为&p->y 指向的字节还没有有效的类型,并且赋值导致下一个sizeof(int) 字节成为int 类型的对象。

【讨论】:

  • 但是,如果在那之后char *p = x; p = "hello" 似乎打印正常(带有警告)。结构也一样。发生了什么事?
  • @blue_note C 可让您自动在任何指针类型之间进行转换,如果我理解正确的话,这就是您所看到的。
  • @blue_note 您不会更改从malloc 返回的内存。您正在更改 p 以指向一个字符串常量。第二个赋值覆盖第一个的结果。
  • @dbush:好的,字符串文字是一个不好的例子。但是,如果我分配了足够的内存(例如malloc(10000)),那么进行结构分配或任何其他分配是否安全??
  • @EricPostpischil 转换为char * 不是有例外吗?
猜你喜欢
  • 2015-06-03
  • 2015-02-27
  • 1970-01-01
  • 2015-01-20
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
  • 2015-12-15
相关资源
最近更新 更多