EN VI

Arrays - Is there a syntax in C to DIRECTLY INIT a struct member that is a const array of constant literal?

2024-03-12 00:00:10
Arrays - Is there a syntax in C to DIRECTLY INIT a struct member that is a const array of constant literal?

Suppose, I work with objects that have properties. Let's say : shape, colour and size. And each property as a list of valid options. For example, shape : circle or square, colour : orange or yellow or white or red and size : large or medium or small.

For each property, I use C structures to work with them. See the code below for a simple example :

#include <stdio.h>

typedef struct {
  const char* name;
  const int nb;
  const char* const* list;
} valid_options_t;

void print_options (const valid_options_t* option) {
  printf("Option Name : %s\n",option->name);
  for (int i=0; i < option->nb; i++) printf("\t%s\n",option->list[i]);
  printf("---------\n");
}
int main() {

  const char* const my_size_optslist[] = {"large", "medium", "small"};
  const valid_options_t my_size_opts = {.name="size", .nb=3, .list=my_size_optslist};
  
  const char* const my_color_optslist[] = {"orange", "yellow", "white", "red"};
  const valid_options_t my_color_opts = {.name="color", .nb=4, .list=my_color_optslist};
  
  const char* const my_form_optslist[] = {"circle", "square"};
  const valid_options_t my_form_opts = {.name="circle", .nb=2, .list=my_form_optslist};

  print_options (&my_size_opts);
  print_options (&my_color_opts);
  print_options (&my_form_opts);

}

The name of properties and their options are constant strings because they are the only available (enum types are not used because these strings are used in a input text file). Everything is known at compile time.

This code works fine. But I wonder if it is possible to merge the two init lines of each option in one line to avoid the declaration of my_xxx_optslist variables that are only used here.

For example, is it possible to replace

  const char* const my_size_optslist[] = {"large", "medium", "small"};
  const valid_options_t my_size_opts = {.name="size", .nb=3, .list=my_size_optslist};

with something like that :

  const valid_options_t my_size_opts = {.name="size", .nb=3, .list={"large", "medium", "small"}};

Solution:

You can use a compound literal:

  const valid_options_t my_size_opts = {.name="size", .nb=3,
       .list = (const char *[]) { "large", "medium", "small" }
    };

The form of a compound literal is (Type) { Initializer-List… }. That is not a cast even though it has a similar form, a type inside parentheses. It creates an object of the indicated type, initialized with the given initializers.

A compound literal outside a function has static storage duration. Inside a function, it has automatic storage duration. Additional options are expected to become available in the next revision of the C standard.

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login