c中的静态数组初始化的大小通过定义中的内容?

发布于 2025-02-01 08:42:59 字数 3026 浏览 2 评论 0 原文

中的数组初始化 - 但我仍然无法分辨我的所有机会是否耗尽。

考虑以下示例文件(我在 https://www.onlinegdb.com/onlinegdb.com/online_c_compiler 可以处理多个文件)

ext.h

#include <inttypes.h>

#define _my_data  0x11, 0x22, 0x33, 0x44, 0x55, 0x66
extern const uint8_t mydata_arr[];

ext.c

#include "ext.h"

const uint8_t mydata_arr[] = { _my_data };

main.c 代码>

#include <stdio.h>
#include "ext.h"

int main()
{
    printf("First mydata_arr item: 0x%02X\n", mydata_arr[0]); // ok
    printf("  size: %d\n", sizeof(mydata_arr));
    return 0;
}

这会失败:

main.c:15:34: error: invalid application of ‘sizeof’ to incomplete type ‘const uint8_t[]’ {aka ‘const unsigned char[]’}
   15 |     printf("  size: %d\n", sizeof(mydata_arr));
      |                                  ^

我在 https://www.reddit.com/r/c_programming/comments/comments/esu4ff/error_invalid_application_of_sizeof_sizeof_to_incoldete/ffc6u19/ 我想总结了问题:

编译器实际上无法在启动文件之外看到任意定义或#COMLUD的内容,因为定义可能还不存在(或根本不存在,直到加载时间或根本不存在)。

编译器分别编译每个源文件,并引用需要由链接器处理的外部源文件中的元素。这就是为什么我们通常要么通过功能原型中的长度的数组...

如果编译器无法直接看到事物的大小,则无法为您提供尺寸的值。

好的,所以我明白为什么我无法从标题文件中获得 sizef(mydata_arr) extern const uint8_t mydata_arr []

但是,事实是 - 我的数据实际上是在 #define _my_data 中(但是,由于缺乏报价标记,这不是字符串 - 尽管我不确定预处理器如何否则如何看待 _MY_DATA的内容)。

因此,我想知道:C中有没有办法使用“ Define” _MY_DATA ,以获取相应数组的大小 - 而无需一定必须使用 sizeof < /code>,哪些需要明确说 extern const uint8_t mydata_arr [6]; 在标题文件中?

编辑:

  • 问题是错误的(值得庆幸的是,接受的答案回答了我想问什么,而不是我写的 :) )。应该是:C中是否有一种方法可以使用“ Define” _MY_DATA ,以获取相应数组的大小 - 以这种方式,我不必显式指定大小通过 extern const uint8_t mydata_arr [6] 在标题文件中 - 但是我仍然可以在代码中使用 sizeof ,以获取数组中的正确大小(元素数)?
  • 我需要在标题文件中将声明为 extern ,因为在我的实际用例中,其他文件以外的其他文件 ext.c main.c 要使用 mydata_arr - 所有这些原则都需要知道 sizeof mydata_arr ;
  • 我宁愿不将 mydata_arr 的元素计数/数量持续到一个单独的变量中 - 考虑到已经存在 sizeof

There is a similar discussion on Count number of elements for static array initialization in C - but I still cannot tell if all the opportunities in my case are exhausted or not.

Consider the following example files (I ran these in https://www.onlinegdb.com/online_c_compiler which can handle multiple files)

ext.h

#include <inttypes.h>

#define _my_data  0x11, 0x22, 0x33, 0x44, 0x55, 0x66
extern const uint8_t mydata_arr[];

ext.c

#include "ext.h"

const uint8_t mydata_arr[] = { _my_data };

main.c

#include <stdio.h>
#include "ext.h"

int main()
{
    printf("First mydata_arr item: 0x%02X\n", mydata_arr[0]); // ok
    printf("  size: %d\n", sizeof(mydata_arr));
    return 0;
}

This fails with:

main.c:15:34: error: invalid application of ‘sizeof’ to incomplete type ‘const uint8_t[]’ {aka ‘const unsigned char[]’}
   15 |     printf("  size: %d\n", sizeof(mydata_arr));
      |                                  ^

The comment(s) I found in https://www.reddit.com/r/C_Programming/comments/esu4ff/error_invalid_application_of_sizeof_to_incomplete/ffc6u19/ I think sums up the problem:

The compiler can’t practically see arbitrary definitions outside of the starting file or what it #includes, because definitions might not exist yet (or at all, up until load time, or at all, ever).

the compiler compiles each source file individually, with references to elements in external source files that need to be handled by the linker. This is why we generally either pass an array with a length in the function prototype ...

If the compiler can’t directly see the size of the thing, it can’t give you a value for sizeof.

OK, so I understand why I cannot get sizeof(mydata_arr) for a extern const uint8_t mydata_arr[] from a header file.

The thing is, though - my data is actually in a #define _my_data (which is however not a string, due to lack of quotation marks - though I'm not really sure how the preprocessor otherwise sees the contents of _my_data).

So, I was wondering: is there a way in C to use the "define" _my_data, to obtain the size of the corresponding array -- without necessarily having to use sizeof, which would require to explicitly say extern const uint8_t mydata_arr[6]; in the header file?

EDIT:

  • Question was wrongly worded (thankfully the accepted answer answered what I wanted to ask, instead of what I wrote :)). It should have been: is there a way in C to use the "define" _my_data, to obtain the size of the corresponding array - in such a way, that I do not have to specify the size explicitly via extern const uint8_t mydata_arr[6] in the header file - but I can still use sizeof in code, to get the correct size (number of elements) in the array?
  • I need to have the declaration as extern in a header file, because in my actual use case, other files than ext.c and main.c would want to use mydata_arr - and all of these would in principle want to also know the sizeof mydata_arr;
  • I'd rather not hold the count/number of elements of mydata_arr in a separate variable - considering that sizeof already exists

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

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

发布评论

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

评论(1

孤单情人 2025-02-08 08:42:59

在声明 mydata_arr 时,您可以将复合文字用作 sizeof 的操作数。


#define _my_data  0x11, 0x22, 0x33, 0x44, 0x55, 0x66
extern const uint8_t mydata_arr[sizeof ((uint8_t[]) {_my_data}) / sizeof(uint8_t)];
                                        ^^ compound literal ^^

顺便提一句。 sizeof(uint8_t)可以保证为 1 ,因为它的大小是 unsigned char 的相同大小(尽管从技术上讲它们不必是相同类型)。

You could use a compound literal as an operand of sizeof when declaring mydata_arr.


#define _my_data  0x11, 0x22, 0x33, 0x44, 0x55, 0x66
extern const uint8_t mydata_arr[sizeof ((uint8_t[]) {_my_data}) / sizeof(uint8_t)];
                                        ^^ compound literal ^^

BTW. The sizeof(uint8_t) is guaranteed to be 1 as it is the same size of unsigned char (though technically they don't have to be same type).

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