pgcc编译C代码出现int与void*类型不兼容警告如何解决
问题背景
使用pgcc编译器编译如下C代码段时持续收到编译警告,无法定位代码问题,涉及代码、编译警告及错误原因如下:
问题代码
#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); }
编译警告输出
"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;
错误根因
所有警告来自同一设计错误:代码试图用int类型变量存储内存指针地址。
当前主流64位环境下,指针类型宽度为8字节,而标准int类型宽度仅为4字节,二者宽度不匹配,直接做比较、传参、赋值转换时会触发类型不兼容、数据截断问题,对应三条警告的触发逻辑:
- 第19行警告:
*nextptr类型为int,NULL本质是void*类型空指针常量,不同类型值直接比较属于非法操作。 - 第25行警告:
realloc接口第一个形参要求为void*类型内存地址,实际传入的*nextptr是int类型整数,参数类型不匹配。 - 第29行警告:将8字节宽的
void*指针强制转换为4字节宽的int类型时,会丢失指针高4位数据,属于会引发内存访问错误的不安全转换。
修正方法
将用于存储指针地址的nextptr形参类型从int*修改为void**即可消除所有警告;如果该函数是供Fortran调用的兼容接口,需要用整数类型传递地址时,应使用<stdint.h>中定义的、与指针等宽的intptr_t类型替代int。
修正后核心代码示例:
#include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <stdint.h> #ifdef _CRAY int MEMALLOC (nextptr, size) #else #ifdef POST_UNDERSCORE int memalloc_ (nextptr, size) #else int memalloc (nextptr, size) #endif #endif int *size; // 二选一:纯C场景用void**,Fortran传整数地址场景用intptr_t* void **nextptr; // intptr_t *nextptr; { void *ptr; if (*nextptr == NULL) { ptr = malloc(*size); if (ptr == NULL) { return(-1); } } else { ptr = realloc(*nextptr, *size); if (ptr == NULL) { return(-1); } } *nextptr = ptr; return (0); }
注:C语言中
malloc、realloc返回值本身为void*类型,不需要额外做强制类型转换。
内容的提问来源于stack exchange,提问作者Surya Sarvajith
相关产品推荐
相关产品推荐

