C Basics: Make Configuration Fields Explicit with Designated Initializers
A positional initializer becomes hard to read when several fields have similar types. Name the fields, then inspect the initialized configuration.
Prepare a scratch directory
Tested on Linux amd64 with GCC 14.2.0. You need GCC with C17 support, Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. No external library is required.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as designated-initializers-demo.c:
#include <stdbool.h>
#include <stdio.h>
enum connection_state { CONNECTION_IDLE, CONNECTION_READY };
struct connection_options {
unsigned retry_limit;
bool verbose;
enum connection_state state;
};
int main(void) {
struct connection_options options = {
.state = CONNECTION_READY,
.retry_limit = 3
};
printf("Retries: %u\n", options.retry_limit);
printf("Verbose: %s\n", options.verbose ? "yes" : "no");
printf("Ready: %s\n", options.state == CONNECTION_READY ? "yes" : "no");
return 0;
}Compile and run it. The program runs only if compilation succeeds:
gcc -std=c17 -Wall -Wextra -Werror -pedantic designated-initializers-demo.c -o designated-initializers-demo &&
./designated-initializers-demoObserved output:
Retries: 3
Verbose: no
Ready: yesRead the result
The field names make the initializer independent of declaration order. The omitted boolean field starts false. An enum gives the state a name rather than scattering numeric codes through callers.
Apply it carefully
Adding a new field still requires reviewing whether its zero value is a sensible default. An enum is not input validation: validate external integers before treating them as states. Avoid serializing this struct directly; padding and enum representation are not a file-format contract.
See the GCC designated-initializer documentation for the underlying language rules.
Clean up
Remove only the source and executable created here, return to the starting directory, and remove the empty practice directory:
rm -- designated-initializers-demo.c designated-initializers-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.