简体   繁体   中英

Const array of const strings and ERROR “not a compile-time constant”

I want to make modular, enumerated matrix of const strings.

I have made two typedefs

globals.h

   #define PAGES_COUNT              8
   #define PARAMETERS_COUNT     8

   typedef const char* const rom_string;
   typedef rom_string const* const rom_string_array;

pages.h

    #include "globals.h"

    typedef enum page_enum{
        PAGE_1_ENUM,
        PAGE_2_ENUM,
    }page_enum;

    extern rom_string pages_names[PAGES_COUNT];
    extern rom_string_array page_list[PAGES_COUNT];

pages.c

#include "globals.h"
#include "pages.h"
#include "page_1.h"
#include "page_2.h"

    rom_string pages_names[PAGES_COUNT] = {
        [PAGE_1_ENUM]   = page_1_name,
        [PAGE_2_ENUM]   = page_2_name,
    };

    rom_string_array page_list[PAGES_COUNT] = {
        [PAGE_1_ENUM]   = page_1,
        [PAGE_2_ENUM]   = page_2,
};

page_1.h

    typedef enum page_1_params{
        PAGE_1_PARAMETER_A,
        PAGE_1_PARAMETER_B,
        PAGE_1_PARAMETER_C,
        PAGE_1_PARAMETER_D,
        PAGE_1_PARAMS_END,
    }page_1_params;

    #define PAGE_1_PARAMS_COUNT (PAGE_1_PARAMS_END)

    extern rom_string       page_1_name;
    extern rom_string_array page_1[PARAMETERS_COUNT];

page_1.c

#include "globals.h"
#include "page_1.h"

    rom_string  page_1_name = "page1.";

    rom_string_array page_1[PARAMETERS_COUNT] = {
        [PAGE_1_PARAMETER_A]    = "text1",
        [PAGE_1_PARAMETER_B]    = "text2",
        [PAGE_1_PARAMETER_C]    = "text3",
        [PAGE_1_PARAMETER_D]    = "text4",
        [PAGE_1_PARAMS_END]     = "",
    };

page_2.h

#include "globals.h"

    typedef enum page_2_params{
        PAGE_2_PARAMETER_A,
        PAGE_2_PARAMETER_B,
        PAGE_2_PARAMETER_C,
        PAGE_2_PARAMETER_D,
        PAGE_2_PARAMS_END,
    }page_2_params;

    #define PAGE_2_PARAMS_COUNT (PAGE_2_PARAMS_END)

    extern rom_string       page_2_name;
    extern rom_string_array page_2[PARAMETERS_COUNT];

page_2.c

#include "globals.h"
#include "page_2.h"

    rom_string  page_2_name = "page2.";

    rom_string_array page_2[PARAMETERS_COUNT] = {
        [PAGE_2_PARAMETER_A]    = "text5",
        [PAGE_2_PARAMETER_B]    = "text6",
        [PAGE_2_PARAMETER_C]    = "text7",
        [PAGE_2_PARAMETER_D]    = "text8",
        [PAGE_2_PARAMS_END]     = "",
    };

Problem 1: the warning I have tried "small" prototype in online C compiler and have no warnings, but on my main "XC8" i've got a next warning message, one for the each parameter of each array:

incompatible pointer types initializing 'rom_string_array' (aka 'const char *const *const') with an expression of type 'rom_string_array [8]' [-Wincompatible-pointer-types]

[8] here is from array size macro . It differs for different arrays.

Problem 2: the error

error: initializer element is not a compile-time constant

This error occurs for the element:

[PAGE_1_ENUM]   = page_1_name,

of pages_names array. If im deleting this element, error occurs on the next one. With a page_list ive have same situation. Its not sensible for me, i think this is a linker job. So what i must do, include ALL in one file? Can i some how get around this?

Reworked upon request.

When you declare a variable like this with rom_string_array :

rom_string_array my_array[SIZE];

It is the same as:

rom_string const* const my_array[SIZE];

Which is the same as:

const char* const const* const my_array[SIZE];

So what you're declaring (ignoring the const quantifiers for now) is not an array of char * but an array of char ** . You should do away with rom_string_array entirely and create your arrays like this:

rom_string my_array[SIZE];

Regarding the "initializer element is not a compile-time constant" error, variables defined at file scope may only be initialized, as the error message says, with a compile time constant. This includeds numeric constants, string constants, and simple expressions involving those, as well as preprocessor macros that expand to one of these. It does not include other variables even if they are declared const .

So you'll need to change page_2_name to a macro to allow it to be used as an initializer, ie:

#define page_2_name "page1."

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM