gpt4 book ai didi

转换函数类型,同时将其作为参数发送到 'qsort'

转载 作者:太空宇宙 更新时间:2023-11-04 01:28:21 24 4
gpt4 key购买 nike

typedef void* ListElement;
typedef int(*CompareListElements)(ListElement, ListElement);

ListResult listSort(List list, CompareListElements compareElement) {
.
.
.
qsort(arr, size, sizeof(*arr), compareElement);
.
.
.
}

前两行是为了阐明什么是CompareListElements。当我将 compareElement 作为参数发送给库函数“qsort”时,我收到以下警告消息:

passing argument 4 of 'qsort' from incompatible pointer type [enabled by default]

我该如何解决这个问题?

最佳答案

避免未定义的行为

重写比较器,使其与 qsort() 期望的相匹配:

typedef int (*CompareListElements)(const void *, const void *);

在比较器内部,转换为正确的类型:

int compare_elements(const void *v1, const void *v2)
{
const RealType *p1 = v1;
const RealType *p2 = v2;
…do comparison…
return …;
}

这样一来,您根本就不会强制转换函数指针。 RealType 是隐藏在(选择不当)后面的类型:

typedef void *ListElement;

真实类型不是void;它可能是某种结构类型。请注意,使用 void * 作为列表元素类型几乎失去了 C 可用的所有类型安全性(可以说这已经足够少了)。你会做得更好:

typedef struct Element ListElement;

或类似的东西,并将指针传递给 ListElement 。 (另请参阅 Is it a good idea to typedef pointers?。您可能还会发现 How to sort an array of structs in C? 有帮助,并且毫无疑问还有其他相关问题会有所帮助。)

为什么转换会导致未定义的行为?

请注意,根据 C 标准,转换函数指针会导致未定义的行为:

C11 §6.3 Conversions — §6.3.2.3 Pointers ¶8

A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

因此,虽然允许转换与 qsort() 预期不匹配的函数指针,但问题是 qsort() 将调用它作为转换后的类型,通常不是 compatible函数的类型,所以行为是未定义的——尽管 Unix 万神殿中的半神发布了相反的例子。

通常,您会侥幸逃脱,但标准表明您不一定总能逃脱惩罚。由于修复相当简单,所以使用它;避免未定义的行为。

关于转换函数类型,同时将其作为参数发送到 'qsort',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27338037/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com