“指针/整数类型不匹配”的编译错误,通常发生在混合使用指针和整数类型的条件表达式中,比如以下代码。
该代码片段使用宏和_Generic
来确定不同数据类型的格式说明符:
#include <stdio.h>
#include <wchar.h>
#define TO_VOID_PTR(P) (1 ? (P) : (void *)(P))
#define PTR_FMT(P) \
_Generic(TO_VOID_PTR(P), \
void const *: "%p", \
void * : "%p" \
)
#define PRINTF_FMT(T) \
_Generic((T), \
_Bool : "%d", \
char : "%c", \
signed char : "%hhd", \
unsigned char : "%hhu", \
short int : "%hd", \
int : "%d", \
long int : "%ld", \
long long int : "%lld", \
unsigned short int : "%hu", \
unsigned int : "%u", \
unsigned long int : "%lu", \
unsigned long long int : "%llu", \
float : "%f", \
double : "%f", \
long double : "%Lf", \
char * : "%s", \
wchar_t * : "%ls", \
default : PTR_FMT(T) \
)
#define print(x) printf(PRINTF_FMT(x), x)
#define println(x) printf(PRINTF_FMT(x), x), putchar('\n')
int main(void)
{
println("hello");
println(10);
println(5u);
println('A');
}
使用GCC编译,并带有以下标志-std=c23 -O3 -Werror -Wall -Wextra
时,该代码会导致以下错误:
error: pointer/integer type mismatch in conditional expression ('int' and 'void *')
错误来自于TO_VOID_PTR
宏:
#define TO_VOID_PTR(P) (1 ? (P) : (void *)(P))
这个宏在条件表达式中混合了指针和整数类型,导致了类型不匹配。
解决方案
要避免混合指针和整数类型。可以直接将值转换为const void *
,以确保类型一致。
修正后的代码:
#include <stdio.h>
#include <wchar.h>
#define TO_CONST_VOID_PTR(P) ((const void *)(P))
#define PTR_FMT(P) \
_Generic(TO_CONST_VOID_PTR(P), \
void const *: "%p", \
void * : "%p" \
)
#define PRINTF_FMT(T) \
_Generic((T), \
_Bool : "%d", \
char : "%c", \
signed char : "%hhd", \
unsigned char : "%hhu", \
short int : "%hd", \
int : "%d", \
long int : "%ld", \
long long int : "%lld", \
unsigned short int : "%hu", \
unsigned int : "%u", \
unsigned long int : "%lu", \
unsigned long long int : "%llu", \
float : "%f", \
double : "%f", \
long double : "%Lf", \
char * : "%s", \
wchar_t * : "%ls", \
default : PTR_FMT(T) \
)
#define print(x) printf(PRINTF_FMT(x), x)
#define println(x) printf(PRINTF_FMT(x), x), putchar('\n')
int main(void)
{
println("hello");
println(10);
println(5u);
println('A');
}