Search code examples
ccompiler-warnings

search.h c header code generating warnings. How to solve it?


TAKEN FROM: https://linux.die.net/man/3/hsearch_r Using these files you can reproduce the warnings. This is the header file that was missing. It has been added.

morse_code.h

#ifndef MORSE_CODE_H
#define MORSE_CODE_H
/* HASH TABLE HEADER  */ 
#include <search.h>
/* Define system variables for hash table. */
ENTRY e;
ENTRY *ep;

/* Define Morse symbols string array */
static char * morse_symbol_str[] = {
    ".-",    "-...",    "-.-.",    "-.."    
};

/* Define Corresponding characters */
static char morse_char_arr[] = {
    'A','B','C','D'
};

static void load_morse_code_into_hashtable(void) {
    const size_t capacity = sizeof(morse_symbol_str) / sizeof(morse_symbol_str[0]);
    hcreate(capacity);
    /* Assign Values to the hash table */
    for (size_t i = 0; i < capacity; i++) {
        e.key = morse_symbol_str[i];
        e.data = (void*) morse_char_arr[i];
        ep = hsearch(e, ENTER);
        /* Ensure that there is no failure */
        assert(ep != NULL && "LOADING MORSE CODE HASH TABLE FAILED!!!");
    }
}

#endif

This is the main.c file that gets compiled. main.c

/* Include required standard library headers. */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>

#include "morse_code.h"

int main(void) {
    load_morse_code_into_hashtable();
    e.key = ".-";
    ep = hsearch(e, FIND);
    printf("%s = %c\n", e.key, (char)ep->data);
    hdestroy();
    return EXIT_SUCCESS;
}

according to search.h manual in Linux this is good code. but I get warnings. How can I change the code so that it would not generate these warnings.

Compiling and linking files...
src/headers/morse_code.h: In function 'load_morse_code_into_hashtable':
src/headers/morse_code.h:25:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   25 |   e.data = (void*) morse_char_arr[i];
      |            ^
src/main.c: In function 'main':
src/main.c:7:29: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    7 |  printf("%s = %c\n", e.key, (char)ep->data);
      |                             ^
An executable MorseCodeDecoder has been created

Solution

  • item.data is a void pointer. Therefore, one has to pass a pointer. In my case I should pass the pointer pointing to the address of the char in memory.

    which is done by the line item.data = (void*) &morse_char_arr[i]; Then to access the char one can use printf("%s = %c\n", item.key, *(char*)item_ptr->data);

    /* Include required standard library headers. */
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <ctype.h>
    #include <assert.h>
    #include <string.h>
    
    /* HASH TABLE HEADER  */ 
    #include <search.h>
    
    /* GLOBAL VARIABLES */
    ENTRY item;
    ENTRY* item_ptr;
    
    /* Define Morse symbols string array */
    static char * morse_symbol_str[] = {
        ".-",    "-...",    "-.-.",    "-.."    
    };
    
    /* Define Corresponding characters */
    static char morse_char_arr[] = {
        'A','B','C','D','E','F','G','H','I','J','K','L','M',
        'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9','&','(',')',
        '+','=','!','?','-',39,'"','/',',','@',':','.'
    };
    
    static struct hsearch_data *load_morse_code_into_hashtable(void) {
        const size_t capacity = sizeof(morse_symbol_str) / sizeof(morse_symbol_str[0]);
        /* Allocate memory for the hash table pointer */
        struct hsearch_data* hashtable = malloc(sizeof(struct hsearch_data*)); 
        /* Create the hash table */
        hcreate_r(capacity, hashtable);
        /* Create hast table item and item pointer */
        /* Assign Values to the hash table */
        for (size_t i = 0; i < capacity; i++) {
            /* Load key and data into an hash-table item */
            item.key = morse_symbol_str[i];
            /* item.data is a void pointer 
             * Therefore, one has to pass a pointer
             * In my case I should pass the pointer pointing to the 
             * address of the char
             */ 
            item.data = (void*) &morse_char_arr[i];
            /* Ensure that there is no failure and load item into the table */
            assert("FAILED TO LOAD ITEM INTO HASHTABLE" &&  \
                    hsearch_r(item, ENTER, &item_ptr, hashtable)
            );
        }
        /* Return the hash table */
        return hashtable;
    }
    
    static void clear_hashtable(struct hsearch_data *hashtable) {
        hdestroy_r(hashtable);
        free(hashtable);
    }
    
    int main(void) {
        struct hsearch_data* hashtable = load_morse_code_into_hashtable();
        item.key = ".-";
        hsearch_r(item, FIND,&item_ptr,hashtable);
        printf("%s = %c\n", item.key, *(char*)item_ptr->data);
        clear_hashtable(hashtable);
        return EXIT_SUCCESS;
    }