1

Consider the following common array definition, note that the array itself has to includes total size:

#define BUFSZ 3
uint8_t buffer[BUFSZ] = {
    BUFSZ, 0xFF, 0x00
}

This is not very handy when you change the buffer alot and it gets large enough that keeping track of every change is easier than counting from scratch each time. Of course, something like this is possible:

#define BUFSZ 3
uint8_t buffer[BUFSZ] = {
    sizeof(buffer), 0xFF, 0x00
}

or conversely

#define BUFSZ 3
uint8_t buffer[] = {
    BUFSZ, 0xFF, 0x00
}

But a combination of the two rquiring no counting at all is not possible:

uint8_t buffer[] = {
    sizeof(buffer), 0xFF, 0x00
}

which results in
invalid application of 'sizeof' to incomplete type 'uint8_t[]' {aka 'unsigned char[]'}
Note I am using the arm-none-eabi-gcc compiler, but this also applies to gcc.

What is the best practice for a situation where you need to define a array at compile time which needs to store its size?
I guess an option could be to reserve that spot and set it at runtime, which in my case could work, but could also prevent it to be saved in read only memory.

5
  • 2
    I'm afraid there's no way to do this in C. The best thing you can do is your first example. Besides, the array size in the [] case is not known to the compiler until it finishes parsing the initializer. Commented Mar 30, 2020 at 18:51
  • Depending on your use case, generating such arrays externally might be an option: Generate a data file with your arrays with a script or with a separate program, then include that file. Integrate the generation into your build procedure. Commented Mar 30, 2020 at 18:58
  • Thanks, that's unfortunate. Yeah for some data it would make sense, although this is hardcoded USB setup data so that'll have to do for now. Will overwrite that position with a sizeof at runtime for now, at least during active development. Commented Mar 30, 2020 at 19:03
  • 1
    If you are not afraid of macros, you could write a macro that determines the number of arguments by using the sizeof(a) / sizeof(*a) trick on a compound array literal: see here. Commented Mar 30, 2020 at 19:10
  • ^^ I quite like that, requires a bit of modification to set the size at a specific position, but it still allows for an array-like entry of the data Commented Mar 30, 2020 at 22:40

1 Answer 1

1
#define  INIT   0xFF, 0x00
#define  SOF(x) (sizeof((char []){x})+1)

char buffer[] =
{
    SOF(INIT) , INIT
};

or

#define  SOF(name, ...) char name[] = {(sizeof((char []){__VA_ARGS__})+1), __VA_ARGS__}

SOF(buffer,255,0);
Sign up to request clarification or add additional context in comments.

2 Comments

Interesting option, circumvents the "incomplete type" error quite nicely by creating a separate array. Although the data will be a pain to enter now, with all those \
@Seneral or singlew line vesion. See the amended answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.