Home > OS >  gcc.exe warning cast from pointer to integer of different size [-Wpointer-to-int-cast]
gcc.exe warning cast from pointer to integer of different size [-Wpointer-to-int-cast]

Time:06-04

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef void SeqList;
typedef void SeqListNode;
typedef unsigned int TSeqListNode;

typedef unsigned int TSeqListNode;
typedef struct _tag_SeqList
{
    int capacity; 
    int length; 
    TSeqListNode *node;
}TSeqList;

SeqList * SeqList_Create(int capacity)
{
    TSeqList *ret = NULL;
    if(capacity>=0)
    {
        ret = (TSeqList *)malloc(sizeof(TSeqList)   sizeof(TSeqListNode)*capacity);
    }
    if(ret == NULL)
    {
        printf("malloc fail.\n");
        exit(-1);
    }
    ret->capacity = capacity;
    ret->length = 0;
    ret->node = (TSeqListNode*)(ret 1);
    return ret;
}

int SeqList_Insert(SeqList *list, SeqListNode *node, int pos)
{
    TSeqList *sList = (TSeqList*)list; 
    int ret = (sList != NULL);
    int i = 0;
    ret = ret && (sList->length 1 <= sList->capacity);
    ret = ret && (0 <= pos);
    if(ret)
    {
        if(pos >= sList->length)
        {
            pos = sList->length;
        }
        for(i=sList->length; i > pos; i--)
        {
            sList->node[i] = sList->node[i-1]; 
        }
        sList->node[i] = (TSeqListNode)node;
        sList->length  ;
    }
    return ret;
}

int main()
{
    system("pause");
    return 0;
}
D:\mingw64\bin\gcc.exe -g D:\Cpp\DSA\test001.c -o D:\Cpp\test001.exe
D:\Cpp\test001.c: In function 'SeqList_Insert':
D:\Cpp\test001.c:56:26: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
         sList->node[i] = (TSeqListNode)node;
                          ^

CodePudding user response:

What you are trying to do is already part of the ISO/IEC 9899:1999 C standard. It's called flexible array member. So no need for inventing your own code - just use what is already available.

Also notice that capacity and length are variables that can't be negative. So you should use an unsigned type. The common used type would be size_t.

So your code should be:

typedef struct _tag_SeqList
{
    size_t capacity; 
    size_t length; 
    TSeqListNode node[];  // Flexible array member
} TSeqList;

Now you can simply do:

ret = malloc(sizeof(TSeqList)   sizeof(TSeqListNode)*capacity);
             \--------------/   \----------------------------/
              Memory for the       Memory for the 'node' array
              struct, i.e for       with 'capacity' elements
              capacity and
              length

to allocate (no need for checking the value of capacity as it can't be negative).

And just use node as a normal array.

All the need for casts are gone.

CodePudding user response:

Earlier versions of the C standard (C90) probably do necessitate casting. I think a placeholder data (int *)(array 1) is entirely appropriate in some situations, assuming alignment is respected. Note that you might also make this design decision to comply with MISRA C 2012 Rule 18.7. I have eliminated the obfuscating typedefs and renamed parts of it to reflect what it actually does more clearly. A cast to void * is basically turning off type-checking, (through a typedef or not,) and should be avoided where possible.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct IntArray {
    size_t capacity;
    size_t length;
    int *node;
};

/** @throws[malloc] */
static struct IntArray *IntArray_Create(const size_t capacity)
{
    struct IntArray *ret = NULL;
    ret = malloc(sizeof *ret   sizeof *ret->node * capacity);
    if(ret == NULL) return 0; /* Let the caller decide what to do. */
    ret->capacity = capacity;
    ret->length = 0;
    ret->node = (int *)(ret 1);
    return ret;
}

/** Returns false if the `array` is full or null. Clips `pos` to `array`. */
static int IntArray_Insert(struct IntArray *array, const int node, size_t pos)
{
    if(!array || array->length >= array->capacity) return 0;
    if(pos >= array->length) pos = array->length;
    /* Replaced looping over the array for performance. */
    memmove(array->node   pos   1, array->node   pos, array->length - pos);
    array->length  ;
    array->node[pos] = node;
    return 1;
}

#include <assert.h>

int main(void)
{
    struct IntArray *a;
    if(!(a = IntArray_Create(3))) { perror("fail"); return EXIT_FAILURE; };
    assert(IntArray_Insert(a, 1, 42));
    assert(IntArray_Insert(a, 3, 1));
    assert(IntArray_Insert(a, 2, 1));
    assert(!IntArray_Insert(a, 2, 1));
    free(a);
    return 0;
}

If you are targeting C99 or later, the flexible array member may be useful for this exact reason. If this is part of a macro, the only typedef you really need is typedef int ArrayType;.

  •  Tags:  
  • c
  • Related