1

I try to convert C Code from Standard 11 to 14. I work with gcc 7.5.0 in Ubuntu 20.04. I have the following lines of code

json.h:

extern const struct _json_value json_value_none;

typedef struct _json_object_entry
{
    json_char * name;
    unsigned int name_length;
    
    struct _json_value * value;
    
} json_object_entry;

typedef struct _json_value
{
   struct _json_value * parent;
   json_type type;
   union
   {
      int boolean;
      json_int_t integer;
      double dbl;
      struct
      {
         unsigned int length;
         json_object_entry * values;
      } object;
   } u;

   union
   {
      struct _json_value * next_alloc;
      void * object_mem;

   } _reserved;
} json_value;

json.c

static int new_value (json_state * state,
                      json_value ** top, json_value ** root, json_value ** alloc,
                      json_type type)
{
   json_value * value;
   int values_size;

   if (!state->first_pass)
   {
      value = *top = *alloc;
      *alloc = (*alloc)->_reserved.next_alloc;

      if (!*root)
         *root = value;

      switch (value->type)
      {
         case json_array:

            ...
            break;

         case json_object:

            if (value->u.object.length == 0)
               break;

            values_size = sizeof (*value->u.object.values) * value->u.object.length;

            if (! (value->u.object.values = (json_object_entry *) json_alloc
                  (state, values_size + ((unsigned long) value->u.object.values), 0)) )
            {
               return 0;
            }

            value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;

            ...
            break;
      
      };

      return 1;
   }
   
   ...
   return 1;
}

When I compile, I got dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] for the following line

value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size

I googled and found this link who means that the problem is probably because object_mem is defined with a void *type, who is an undefined type. I tried to substitute it by int * type, without success. I'm stucked.

Any helps are welcome.

1 Answers1

0

Instead of casting the address of the pointer, you should convert its value and write:

value->_reserved.object_mem = (char *)value->u.object.values + values_size;
chqrlie
  • 131,814
  • 10
  • 121
  • 189