A variant on Chris Dodd's suggestion is to wrap your function in a macro:
void real_foo(uint8_t *arr, size_t len);
#define foo(...) real_foo((uint8_t[]) __VA_ARGS__, (sizeof (uint8_t[]) __VA_ARGS__)/sizeof(uint8_t));
// ...
foo({1});
foo({1,2});
Try on godbolt
Note the use of a variadic macro to work around the fact that {1,2}
is parsed as two macro arguments.
For slightly different syntax, you could also write { __VA_ARGS__ }
in the macro definition, so that you can invoke it as
foo(1);
foo(1,2);
You can also macro-ize supercat's solution, if you're willing to use gcc/clang statement expressions (a non-standard C extension):
#define foo(...) ({ static const uint8_t my_array[] = { __VA_ARGS__ }; real_foo(my_array, sizeof(my_array) / sizeof(uint8_t)); })
Or if real_foo()
returns void
, you can do the following which is standard C:
#define foo(...) do { static const uint8_t my_array[] = { __VA_ARGS__ }; real_foo(my_array, sizeof(my_array) / sizeof(uint8_t)); } while (0)
where the do/while
will eat a semicolon.
This of course assumes that real_foo()
doesn't need to modify the array. If it does, this won't work, even without the const
, since the array won't be re-initialized if the code is executed again.
Another option is to redesign your function so that it doesn't need to be told the size of the array. For instance, if there is some value that otherwise isn't valid as an entry of the array, you could use it as a sentinel:
foo((uint8_t []){1, 2, 0xff});