在何时以及何时不在 C 中进行类型转换存在冲突?
conflicted on when and when not to typecast in C?
我正在阅读有关搜索和排序功能的 GLibC 参考资料
here and here 在其中一个代码示例中使用了类型转换,而在另一个示例中则没有:
第一个:
int
compare_doubles (const void *a, const void *b)
{
const double *da = (const double *) a;
const double *db = (const double *) b;
return (*da > *db) - (*da < *db);
}
第二个:
int
critter_cmp (const void *v1, const void *v2)
{
const struct critter *c1 = v1;
const struct critter *c2 = v2;
return strcmp (c1->name, c2->name);
}
在第二个例子中有什么原因,比如
const struct critter *c1 = (const struct critter *)v1;
没用过?或者这样做只是为了简洁?
编辑:如果编译器可以推断出第一个示例中的强制转换是否必要?这种事情有什么最佳实践吗?
与 void *
和任何对象指针类型之间的转换无需强制转换即可安全完成。这在 C standard:
的第 6.3.2.3p1 节中指定
A pointer to void
may be converted to or from a pointer to any
object type. A pointer to any object type may be converted to a
pointer to void
and back again; the result shall compare equal
to the original pointer.
因此,第二个函数可以正常使用,第一个函数可以安全地写成:
int
compare_doubles (const void *a, const void *b)
{
const double *da = a;
const double *db = b;
return (*da > *db) - (*da < *db);
}
一般来说,除非万不得已,否则您不应该施法。
None 是必需的,因为 void *
可以转换为任何指针类型。
我正在阅读有关搜索和排序功能的 GLibC 参考资料 here and here 在其中一个代码示例中使用了类型转换,而在另一个示例中则没有:
第一个:
int
compare_doubles (const void *a, const void *b)
{
const double *da = (const double *) a;
const double *db = (const double *) b;
return (*da > *db) - (*da < *db);
}
第二个:
int
critter_cmp (const void *v1, const void *v2)
{
const struct critter *c1 = v1;
const struct critter *c2 = v2;
return strcmp (c1->name, c2->name);
}
在第二个例子中有什么原因,比如
const struct critter *c1 = (const struct critter *)v1;
没用过?或者这样做只是为了简洁?
编辑:如果编译器可以推断出第一个示例中的强制转换是否必要?这种事情有什么最佳实践吗?
与 void *
和任何对象指针类型之间的转换无需强制转换即可安全完成。这在 C standard:
A pointer to
void
may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer tovoid
and back again; the result shall compare equal to the original pointer.
因此,第二个函数可以正常使用,第一个函数可以安全地写成:
int
compare_doubles (const void *a, const void *b)
{
const double *da = a;
const double *db = b;
return (*da > *db) - (*da < *db);
}
一般来说,除非万不得已,否则您不应该施法。
None 是必需的,因为 void *
可以转换为任何指针类型。