我最近正在研究memmem
,memcmp
和其他此类功能,以教育自己。我获取了glibc源,并复制了需要查看的文件。为了测试实现,我编写了一个main
函数,并使用了该main
中正在研究的函数。由于我主要从事C ++工作,因此我使用C ++编译器(clang ++,g ++)编译代码。它可以正常工作并给出正确的结果。
我想知道的与类型别名有关。在代码中的某些地方会发生这种情况:
#define op_t unsigned long int;
inline int memcmp_common_alignment(
long int srcp1, long int srcp2, std::size_t len )
{
op_t a0, a1;
// some code
a0 = ( (op_t *) srcp1 )[0];
b0 = ( (op_t *) srcp2 )[0];
// rest of code
}
据我可能有误的理解,它与:
inline int memcmp_common_alignment(
long int srcp1, long int srcp2, std::size_t len )
{
op_t a0, a1;
// some code
a0 = reinterpret_cast< op_t* >( srcp1 )[0];
b0 = reinterpret_cast< op_t* >( srcp2 )[0];
// rest of code
}
在我看来,这在C ++中是未定义的行为,因为它从另一种类型读取srcp1
和srcp2
中的值。在here和here等地方对此进行了讨论。
我认为通常的“解决方案”是在C ++中使用memcpy
进行类型校正。如果我正确理解该原理,则想法是将这些位复制到声明为正确类型的内存区域中并对其进行访问。根据我所做的少量研究,优化编译器擅长识别这种惯用法,因此可以很好地对其进行优化。提醒您,有些细节让我不知所措,因为我无法正常工作。
也就是说,我真正的问题是,这是否意味着C标准库的很大一部分实际上不能使用C ++编译器合法地编译(即,用g ++而不是gcc编译glibc)?我的理解是,例如,编译器可以在调用未定义行为时消除这些表达式?
可能与此问题有关: What is the cost of compiling a C program with a C++ compiler? 但是我不确定我是否同意答案。就我上面显示的情况而言,这不是C ++下的未定义行为吗?