sizeof abuse:获取const表的大小

时间:2010-03-26 14:41:09

标签: c sizeof

声明const表时,可以使用sizeof获取表的大小。然而, 一旦停止使用符号名称,它就不再起作用了。有没有办法让以下程序输出表A的正确大小,而不是0?

#include <stdio.h>

struct mystruct {
    int a;
    short b;
};

const struct mystruct tableA[] ={
    { 
        .a = 1,
        .b = 2,
    },
    { 
        .a = 2,
        .b = 2,
    },
    { 
        .a = 3,
        .b = 2,
    },
};

const struct mystruct tableB[] ={
    { 
        .a = 1,
        .b = 2,
    },
    { 
        .a = 2,
        .b = 2,
    },
};


int main(int argc, char * argv[]) {
    int tbl_sz;
    const struct mystruct * table;

    table = tableA;
    tbl_sz = sizeof(table)/sizeof(struct mystruct);
    printf("size of table A : %d\n", tbl_sz);

    table = tableB;
    tbl_sz = sizeof(tableB)/sizeof(struct mystruct);
    printf("size of table B : %d\n", tbl_sz);

    return 0;
}

输出是:

size of table A : 0
size of table B : 2

这是sizeof的预期行为。但是有没有办法让编译器知道const表的大小,给定指向表而不是符号名的指针?

5 个答案:

答案 0 :(得分:5)

你要求指针的大小。这总是指针大小(即32位机器上通常为4个字节,64位机器上为8个字节)。在第二次尝试中,你要求数组的大小,因此你得到了你期望的结果。

答案 1 :(得分:2)

  

在给定指向表而不是符号名的指针的情况下,编译器是否有办法知道const表的大小?

不,因为在编译时评估sizeof()(除非它是VLA,但是VLA不是常量表),并且编译器通常不能告诉指针指向哪个表。当然,在所示的场景中,有可能在C语言的某些假设变体中,但这意味着不同的sizeof()返回的定义,这将是一个更大的问题,而不是得到你可能想要的答案,但不是得到。

所以,正如其他人都巧妙地指出的那样,当你拿出指针的大小时,就会得到指针的大小。假设一个标准的32位机器,因为结果与该假设一致,你的结构是8个字节,你的指针是4个字节,所以除法的结果是零,正如预期的那样。

答案 2 :(得分:1)

不 - 你要求sizeof()一个指针。但是,由于您真正想要获得的是数组中元素的数量,您可以使用一个宏来返回该值,但如果您传递指针而不是数组,通常会给您一个错误:

#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))

有关详细信息,请参阅此SO答案:Is there a standard function in C that would return the length of an array?

使用C ++而不是C时,为了获得更安全的解决方案,请参阅此SO答案,该答案使用模板确保尝试获取指针上的数组计数始终会生成错误:Compile time sizeof_array without using a macro

答案 3 :(得分:1)

简短的回答是否定的;如果你只有一个指针,那么就没有(标准的)方法来获得通过该指针指向的东西的大小。

答案 4 :(得分:0)

虽然在语法上是正确的,但您的样本更常规地写为:

const struct mystruct tableA[] = {
    {1, 2},
    {2, 2},
    {3, 3}, 
};

哪个不那么冗长,因此更具可读性。