Home > Software design >  Size of static array initialization in C via contents in define?
Size of static array initialization in C via contents in define?

Time:05-25

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 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

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).

  • Related