-2

I am using a pgcc compiler to compile the following piece of code. I keep getting this warning and I am not sure what is wrong with it. Here is the code, followed by the warning:

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

#ifdef _CRAY
int MEMALLOC (nextptr, size)
#else
#ifdef POST_UNDERSCORE
int memalloc_ (nextptr, size)
#else
int memalloc (nextptr, size)
#endif
#endif

int *size;
int *nextptr;
{
  void *ptr;
  if (*nextptr == NULL) {
    if ((ptr = (void *) malloc (*size)) == NULL) {
      return(-1);
    }
  }
  else {
    if ((ptr = (void *) realloc (*nextptr, *size)) == NULL) {
      return(-1);
    }
  }
  *nextptr = (int) ptr;
  return (0);

These are the following errors that I get

memalloc.c", line 19: warning: operand types are incompatible ("int" and "void
          *")
    if (*nextptr == NULL) {
                 ^
"memalloc.c", line 25: warning: argument of type "int" is incompatible with
          parameter of type "void *"
      if ((ptr = (void *) realloc (*nextptr, *size)) == NULL) {
                                   ^
"memalloc.c", line 29: warning: conversion from pointer to smaller integer
    *nextptr = (int) ptr;

What am I doing wrong?

1 Answers1

0

As per comments, nextptr should actually be void **. If that change is not feasible and it must remain int *, then you either cast:

if (((void*)*nextptr) == NULL) {

or simply compare to 0:

if (!*nextptr) {
lorro
  • 10,687
  • 23
  • 36
  • `nextptr` is a function out parameter, a pointer to a buffer which receives a result which is itself a pointer... but this ridiculously old code is designed for (apparently) a compiler that didn't support double-pointers. – Ben Voigt Jul 07 '22 at 21:09
  • in that case, compare to `0` – lorro Jul 07 '22 at 21:11
  • What's needed is to properly declare the parameter as a double pointer. – Ben Voigt Jul 07 '22 at 21:12
  • @BenVoigt yes, but it's not sure the user is allowed to do that. E.g. if it's a callback in a library where interface is pre-defined, you cannot change it. – lorro Jul 07 '22 at 21:13
  • One could still introduce a local variable which has the correct type. – Ben Voigt Jul 07 '22 at 21:16
  • @lorro The function must be called with a pointer pointer no matter what the prototype reads. So if you stop lying to the compiler and use `void**` it's only going to make it work better. It's an in/out parameter for a `void*`. – Goswin von Brederlow Jul 07 '22 at 21:21
  • @GoswinvonBrederlow It is typical in some libraries that some data is passed by user to lib, then lib to callback. I.e., lib does not change this. It's usually `int *` or `void *`. In such a case, you're not allowed to change the data type. This also seems like such a case - it's a custom allocator. – lorro Jul 07 '22 at 21:23
  • @lorro That applies to function pointers. And here the `int*` is assigned an address with `*nextptr = (int) ptr;`. That clearly is only valid with a pointer pointer or `intptr_t`. But 40 years ago they where all the same. – Goswin von Brederlow Jul 07 '22 at 21:39
  • I was able to fix the first two warning in my question with the answer above. But I am still stuck with the final warning ``` "memalloc.c", line 29: warning: conversion from pointer to smaller integer *nextptr = (int) ptr; ``` – Surya Sarvajith Jul 07 '22 at 22:03
  • And yes, this code was used about 20 years ago and I am able to compile it but when I execute the executable, I get a message called segmentation fault. I am trying to eliminate all the warning so to see if that would help. – Surya Sarvajith Jul 07 '22 at 22:06
  • @SuryaSarvajith if `static_assert(sizeof(int) != sizeof(int*));` fails, i.e., if pointer and int sizes are different, then you're out of luck with this interface. – lorro Jul 07 '22 at 22:14