I have the following code:
#define SUB_LIST 1, 2, 3
uint8_t sub_array[] = {SUB_LIST};
#define SUB_LIST_SIZE (sizeof(sub_array) / sizeof(sub_array[0]))
uint8_t array[SUB_LIST_SIZE X] = {0};
Here, sub_array[]
exists only because I need it to get the number of elements in SUB_LIST
. It is not used anywhere else, and thus it is quite a waste of memory.
It is possible to get the number of element in SUB_LIST
without having to permanently allocate memory for sub_array[]
?
CodePudding user response:
You can use a compound literal but it gets a bit messy if you want to avoid specifying the element type (here uint8_t
) twice:
#define SUB_LIST_SIZE ( sizeof( (uint8_t[]){SUB_LIST} ) / sizeof(uint8_t) )
With this, a local, unnamed array will be created wherever the SUB_LIST_SIZE
macro's code is encountered. That will be created with automatic storage duration (typically, on the stack), or may even optimized out by the compiler. 1
A short demo:
#include <stdio.h>
#include <stdint.h>
#define SUB_LIST 1, 2, 3
#define SUB_LIST_SIZE ( sizeof( (uint8_t[]){SUB_LIST} ) / sizeof(uint8_t) )
int main()
{
#define X 42 // For example
uint8_t array[SUB_LIST_SIZE X] = { 0 };
size_t arr_length = sizeof(array) / sizeof(array[0]);
printf("Array length = %zu\n", arr_length);
return 0;
}
1 This assumes that the macro is used at block scope, as it is in your declaration of array
in main
; if it is used at file scope, then a static (permanent) unnamed array will be created.
CodePudding user response:
Consider a macro such as this:
#define GET_SIZE(...) ( sizeof (uint8_t[]){ __VA_ARGS__} )
Usage:
GET_SIZE(SUB_LIST)
This creates a temporary compound literal array and places your list of item as initializer list to that array. The compound literal will almost certainly get optimized away in any scenario - in your case it will get replaced by the number 3 in the machine code.