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: 0xX\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 viaextern const uint8_t mydata_arr[6]
in the header file - but I can still usesizeof
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 thanext.c
andmain.c
would want to usemydata_arr
- and all of these would in principle want to also know thesizeof
mydata_arr
; - I'd rather not hold the count/number of elements of
mydata_arr
in a separate variable - considering thatsizeof
already exists
CodePudding user response:
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).