Search code examples
arraysgccconstantsavr-gcc

warning: initialization discards 'const' qualifier from pointer target type


We are in the process of upgrading legacy code to work with a newer version of GCC. (9.1) I have been searching for answers on how to resolve this warning, but I am extremely incompetent and have been struggling understanding what's going on.

I have already tried to remove a constant to make it consistent but I then receive an error because the structure needs to be declared as a constant for ATTR_PROGMEM. I had to add a const keyword after the pointer also to resolve an error, but it turned it into this warning.


#include <avr/pgmspace.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned short UINT16;
typedef unsigned long DWORD;
typedef unsigned long UINT32;


typedef signed char CHAR;
typedef signed short INT;
typedef signed short INT16;
typedef signed long LONG;
typedef signed long INT32;


typedef float FLOAT;
typedef float SINGLE;

typedef char BOOLEAN;

typedef struct {

    BOOLEAN ReadOnly;
    // * Where to display field
    BYTE row;
    BYTE col;
    BYTE field_type;

    union {
        INT16 *i16_ptr;
        BOOLEAN *b_ptr;
        BYTE *str_index;
    } fields;

    struct {
        INT16 minrange;
        INT16 maxrange;
    } range;
    const char **textFields; // Table of text fields if field_type == FIELD_STRINGS
} MENU_FIELD;


typedef struct {
    /** the screen display */
    const char **menuScreen;  // Pointer to a list of string pointers
    const MENU_FIELD *menuFields; // A pointer to the first field definition
} MENU_DEFINITION;

static const char _menuMain_L1_0[] __ATTR_PROGMEM__ =   "    SetPoint  Actual";
/*01234567890      123456789 */
static const char _menuMain_L2_0[] __ATTR_PROGMEM__   = "Temp       \x01" "       \x01";

static const char _menuMain_L3_0[] __ATTR_PROGMEM__ =   "Rh         %" "       %";
static const char _menuMain_L4_0[] __ATTR_PROGMEM__ =   "DP      \x01" " ";

static const char * const _menuMain_Strings_0[] __ATTR_PROGMEM__ = { _menuMain_L1_0,
_menuMain_L2_0, _menuMain_L3_0, _menuMain_L4_0 };

// When you add this line, you get the const error
static const MENU_DEFINITION _menuDef_Main_0 __ATTR_PROGMEM__ = { _menuMain_Strings_0};


int main(void) {
    return 0;

}

Here is the warning output:

../main.c:75:67: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
   75 | static const MENU_DEFINITION _menuDef_Main_0 __ATTR_PROGMEM__ = { _menuMain_Strings_0};

Solution

  • how to resolve this warning

    Cast the menuScreen pointer to be a pointer to const pointer, which is the best option. The _menuMain_Strings_0 is declared with __ATTR_PROGMEM__ which most probably means that it's stored inside some "program memory", not in ram, which means it is immutable and should be declared with const qualifier. So:

    typedef struct {
        /** the screen display */
        const char * const *menuScreen;  // Pointer to a list of string pointers
        const MENU_FIELD *menuFields; // A pointer to the first field definition
    } MENU_DEFINITION;
    

    or change the type of _menuMain_Strings_0:

    static const char * const _menuMain_Strings_0[] __ATTR_PROGMEM__ = { _menuMain_L1_0,
    _menuMain_L2_0, _menuMain_L3_0, _menuMain_L4_0 };
    

    or you can just cast it to void* and live with spagetti code:

    static const MENU_DEFINITION _menuDef_Main_0 __ATTR_PROGMEM__ = { (void*)_menuMain_Strings_0 };