I have a structure:
typedef struct stock {
const char* key1p2; // stock code
const char* key2p2; // short desc
const char* desc1; // description
const char* prod_grp; // product group
const char dp_inqty; // decimal places in quantity
const long salprc_u; // VAT excl price
const long salprc_e; // VAT includive price
const long b_each; // quantity in stock
const long b_alloc; // allocated qty
const char* smsgr_id; // subgroup
const char** barcodes; // barcodes
} stock_t;
and I want to initialise arrays of instances of this structure, in one line of code per stock struct.
I have tried:
stock_t data_stock[] = {
{ "0001", "Soup", "Tomato Soup", "71", 0, 100, 120, 10, 0, "", {"12345", "23456", NULL} },
{ "0002", "Melon", "Melon and Ham", "71", 0, 200, 240, 10, 0, "", {"34567", "45678", NULL} },
...
{ NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL }
};
but it fails with:
data.c:26:74: warning: incompatible pointer types initializing 'const char **' with an expression of type 'char [6]'
[-Wincompatible-pointer-types]
{ "0001", "Soup", "Tomato Soup", "71", 0, 100, 120, 10, 0, "", {"12345", "23456", NULL} },
^~~~~~~
It is the barcode field which is problematic, as it is char**.
(that was clang, but GCC reports a similar error, but less helpfully.)
It’s almost as if the compiler has ignored the curly brace before “12345”.
I can work around the problem using:
const char *barcodes0001[] = {"12345", "23456", NULL};
stock_t data_stock[] = {
{ "0001", "Soup", "Tomato Soup", "71", 0, 100, 120, 10, 0, "", barcodes0001 },
Is the cause of this problem a different between char [] and char *, or is there something more subtle. (Perhaps you can initialise arrays of structs, but not structs of arrays.)
To avoid to have to declare a named dummy variable you can use a compound literal
This is a way to define a local temporary variable with a syntax of
(type){ initializers }which is available since c99 (and clang and gcc have them).Edit: The lifetime of these compound literals is the same as your variable
data_stockso I suppose this is ok. In any case I think you should mark most of your fields also asconst, e.gconst char*const key1p2;Also it would be much easier to read if you’d use designated initializers something like