"The initializer element is not constant", but it is explicitly

I know what the message means, but not why it happened.

main.c:26:2: error: initializer element is not constant
  rgb24_xrgb(0xB14835), // brick red

      

My code:

typedef uint32_t rgb24_t;

// Color structure
typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
} xrgb_t;

// Table of colors
const xrgb_t COLORS[] = {
    rgb24_xrgb(0xB14835), // brick red
    rgb24_xrgb(0x4C1661), // indigo
    rgb24_xrgb(0xA3268E), // royal purple
};

      

Here are my macros:

#define xrgb(rr, gg, bb) ((xrgb_t) { .r = ((uint8_t)(rr)), .g = ((uint8_t)(gg)), .b = ((uint8_t)(bb)) })
#define rgb24_r(c) ((((rgb24_t) (c)) >> 16) & 0xFF)
#define rgb24_g(c) ((((rgb24_t) (c)) >> 8) & 0xFF)
#define rgb24_b(c) ((((rgb24_t) (c)) >> 0) & 0xFF)
#define rgb24_xrgb(c) xrgb(rgb24_r(c), rgb24_g(c), rgb24_b(c))

      

The preprocessor output is here:

const xrgb_t COLORS[] = {
    ((xrgb_t) { .r = ((uint8_t)(((((rgb24_t) (0xB14835)) >> 16) & 0xFF))), .g = ((uint8_t)(((((rgb24_t) (0xB14835)) >> 8) & 0xFF))), .b = ((uint8_t)(((((rgb24_t) (0xB14835)) >> 0) & 0xFF))) }),
    ((xrgb_t) { .r = ((uint8_t)(((((rgb24_t) (0x4C1661)) >> 16) & 0xFF))), .g = ((uint8_t)(((((rgb24_t) (0x4C1661)) >> 8) & 0xFF))), .b = ((uint8_t)(((((rgb24_t) (0x4C1661)) >> 0) & 0xFF))) }),
    ((xrgb_t) { .r = ((uint8_t)(((((rgb24_t) (0xA3268E)) >> 16) & 0xFF))), .g = ((uint8_t)(((((rgb24_t) (0xA3268E)) >> 8) & 0xFF))), .b = ((uint8_t)(((((rgb24_t) (0xA3268E)) >> 0) & 0xFF))) })
};

      

Looks pretty consistent to me.

Where is the problem?

+3


source to share


2 answers


From C11 6.7.9 / 4 (C99 had similar text):

All expressions in an initializer for an object that has static or stream storage duration must be constant expressions or string literals.

From C11 6.6 "Constant Expressions":

Additional latitude is allowed for constant expressions in initializers. Such a constant expression shall be, or be evaluated, one of the following:

  • arithmetic constant expression,
  • a null pointer constant,
  • an address constant or
  • an address constant for a complete object type plus or minus an integer constant expression.

A compound literal is not one of these clauses, so it is not allowed in an initializer.



I see no reason to believe why this is unacceptable if complex literary initializers are all constant expressions that meet these criteria.

However, you can work around this simply by using initializers without a composite literal:

const xrgb_t COLORS[] = {
    { .r = ........... , .g = ............., .b = ........ },
    { .r = .......  // etc.
};

      

It should be easy to do this in your existing code by renaming your macro to just provide the part { }

and then adding another macro with the original name that does (const xrgb_t) rgb24_xrgb(X)

to create a composite literal or whatever.

NB. Creating a compound literal const

allows the compiler to store it in a read-only scope.

+3


source


The following work compiles cleanly it's still a lot ruthless for what it should be:

// Color structure
struct xrgb_t
{
    unsigned char r;
    unsigned char g;
    unsigned char b;
};


#define xrgb(rr, gg, bb) ((struct xrgb_t) { .r = ((unsigned char)(rr)), .g = ((unsigned char)(gg)), .b = ((unsigned char)(bb)) })
#define rgb24_r(c) ((((unsigned char) (c)) >> 16) & 0xFF)
#define rgb24_g(c) ((((unsigned char) (c)) >> 8) & 0xFF)
#define rgb24_b(c) ((((unsigned char) (c)) >> 0) & 0xFF)
#define rgb24_xrgb(c) xrgb(rgb24_r(c), rgb24_g(c), rgb24_b(c))


// Table of colors
const struct xrgb_t COLORS[] =
{
    rgb24_xrgb(0xB14835), // brick red
    rgb24_xrgb(0x4C1661), // indigo
    rgb24_xrgb(0xA3268E), // royal purple
};

      



my preferred method:

struct xrgb_t
{
    unsigned char r;
    unsigned char g;
    unsigned char b;
};

#define set_xrgb(y)  {((y)>>16)&0xFF}, {((y)>>8)&0xFF}, {((y)&0xFF)}
// Table of colors
const struct xrgb_t COLORS[] =
{
    set_xrgb(0xB14835), // brick red
    set_xrgb(0x4C1661), // indigo
    set_xrgb(0xA3268E)  // royal purple
};

      

-1


source







All Articles