1

I have a struct which is defined like this:

typedef struct {
    sn74lvc138a_options_t decoder_opts;
    uint32_t pin_int;
    uint32_t pin_rst;
    uint32_t pin_pwr;
    ...
} w5500_options_t;

The nested struct sn74lvc138a_options_t struct looks like this:

static const sn74lvc138a_options_t sn74lvc138a_opts ={
    .decoder_a = DECODER_A_GPIO,
    .decoder_b = DECODER_B_GPIO,
    .decoder_c = DECODER_C_GPIO,
    .decoder_sel = DECODER_SEL_GPIO
};

These two are stored in two different C modules. One of the C modules (the one which also contains the w5500_options_t instance) has the following function defined:

static const sn74lvc138a_options_t* _get_spi_decoder(void) {
    return cpu_samv71_get_sn74lvc138a();  // This is a function from the other C module
}

I would like to be able to do the following for compile time initialization:

static const w5500_options_t w5500_opts = {
    .pin_int = SOMEVALUE1,
    .pin_rst = SOMEVALUE2,
    .pin_pwr = SOMEVALUE3,
    .decoder_opts = _get_spi_decoder()
};

Basically what I'm trying to do, is to get a reference to a struct instance inside an initialization block. Since the reference itself is defined as const and the function returns a const pointer the compiler should be able to do this (I'm using GCC with C99).

The question is now: Is this not allowed at all or am I doing something wrong which disallows this. The exact error message I get from the compiler is that the "initializer element is not constant".

Tom L.
  • 932
  • 2
  • 9
  • 30
  • 4
    You can't call a function for file scope or static variable initialization. C++ allows; C does not. – Jonathan Leffler Jun 05 '18 at 07:40
  • 2
    Note that you should not create function, variable or macro names that start with an underscore, in general. [C11 §7.1.3 Reserved identifiers](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) says (in part): — _All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use._ — _All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces._ See also [What does double underscore (`__const`) mean in C?](https://stackoverflow.com/a/1449301/15168) – Jonathan Leffler Jun 05 '18 at 07:40
  • @JonathanLeffler: The function is defined as static and has file scope. Is it wrong to use an underscore in that case? Not quite sure what "ordinary and tag spaces" means. Thanks for the heads up on static variable initialization. – Tom L. Jun 05 '18 at 08:05
  • 1
    It’s a function. It doesn’t matter what sort of function; it can’t be used as an initializer for a static variable. – Jonathan Leffler Jun 05 '18 at 08:07
  • I was referring to the name with the underscore, not for the initialization issue. – Tom L. Jun 05 '18 at 08:08
  • 1
    You are treading on thin ice with the leading underscore. Many people do it. Many people get away with it. The standard doesn’t say you can’t do it, but you shouldn’t do it. If you do, you risk failure at any time in the future, and there is no recourse but to change the code so it doesn’t ignore the advice given by the standard. – Jonathan Leffler Jun 05 '18 at 08:13

1 Answers1

2

It is not allowed, for the exact reason the compiler is so helpfully giving you.

Think of the run-time action corresponding to the initialization as being a memcpy() from your executable file and into somewhere in your process' heap; that's all you're getting. A bunch of bits being set to a pre-defined pattern, no functions are getting called.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • I had just hoped that since all elements in that path are declared const that there was a direct way for the compiler to just store that struct in ROM space only instead of both in ROM and RAM. Thanks for the information. – Tom L. Jun 05 '18 at 08:07
  • I'm guessing a sufficiently advanced compiler[*] could figure that out, but since as written the code is not valid (there's a function call where there should be compile-time constant data), it's not a very intuitive optimization to implement. – unwind Jun 05 '18 at 09:05