sizeof 滥用:获取 const 表的大小

发布于 2024-08-26 07:26:32 字数 985 浏览 10 评论 0原文

声明 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 表的大小?

When declaring a const table, it is possible to get the size of the table using sizeof. However,
once you stop using the symbol name, it does not work anymore. is there a way to have the following program output the correct size for table A, instead of 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;
}

Output is :

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

This is the intended behavior of sizeof. But is there a way for a compiler to know the size of a const table, given a pointer to the table instead of the symbol name ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

九八野马 2024-09-02 07:26:32

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

you are asking for the sizeof a pointer. That is always the pointer size (ie usually 4 bytes on a 32-bit machine and 8 bytes on a 64-bit machine). In the 2nd attempt you are asking for the sizeof the array and hence you get the result you'd expect.

娇女薄笑 2024-09-02 07:26:32

有没有办法让编译器知道 const 表的大小,给定指向表的指针而不是符号名称?

不,因为 sizeof() 是在编译时计算的(除非它是 VLA,但 VLA 不是常量表),并且编译器通常无法判断指针是哪个表指向。诚然,在所示的场景中,在 C 语言的某些假设变体中这可能是可能的,但这意味着 sizeof() 返回的内容的定义不同,这将是一个比得不到您可能喜欢但不想要的答案更大的问题得到。

因此,正如其他人巧妙指出的那样,当您获取指针的大小时,您就得到了指针的大小。假设是标准 32 位机器,由于结果与该假设一致,因此您的结构体是 8 字节,指针是 4 字节,因此除法的结果为零,正如预期的那样。

Is there a way for a compiler to know the size of a const table, given a pointer to the table instead of the symbol name?

No, because sizeof() is evaluated at compile-time (unless it is a VLA, but a VLA is not a constant table), and the compiler cannot, in general, tell which table the pointer is pointing to. Granted, in the scenario shown, it might be possible in some hypothetical variation of the C language, but that would mean varying definitions of what sizeof() returns, which would be a bigger problem than not getting the answer you might like but do not get.

So, as everyone else ably pointed out, when you take the size of a pointer, you get the size of the pointer. Assuming a standard 32-bit machine since the results are consistent with that assumption, your structure is 8 bytes and your pointers are 4 bytes, so the result of the division is zero, as expected.

梦在深巷 2024-09-02 07:26:32

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

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

请参阅此答案有关更多详细信息: C 中是否有一个标准函数可以返回数组的长度?

对于使用 C++ 而不是 C 时更安全的解决方案,请参阅此 SO 答案,它使用模板来确保尝试获取指针上的数组计数总是会生成错误: 不使用宏编译时sizeof_array

No - you're asking for the sizeof() a pointer. But since what you're really trying to get is the number of elements in an array, you can use a macro that will return that value but will generally give you an error if you pass a pointer instead of an array:

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

See this SO answer for more details: Is there a standard function in C that would return the length of an array?

For an even safer solution when using C++ instead of C, see this SO answer that uses templates to ensure that trying to get an array count on a pointer will always generate an error: Compile time sizeof_array without using a macro

凌乱心跳 2024-09-02 07:26:32

简短的回答是否定的;如果您拥有的只是一个指针,那么就没有(标准)方法来获取通过该指针所指向的对象的大小。

Short answer is no; if all you have is a pointer, then there's no (standard) way to get the size of the thing being pointed to through that pointer.

阳光下的泡沫是彩色的 2024-09-02 07:26:32

尽管语法正确,但您的示例更传统地写为:

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

不太冗长,因此更具可读性。

Although syntactically correct, your sample is more conventionally written as:

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

Which is less verbose and therefore more readable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文