将 double 传递给 void * 参数的方法

ryy*_*ker 1 c strict-aliasing

我的问题是由于需要double通过void *函数参数正确传递变量。我问,因为在我的机器sizeof(void *)4,和sizeof(double)8,铸造一个到另一个好像它应该产生一个问题,但我的编译器(CLANG,对所有的警告)没有给出一个问题的指示,和代码似乎工作美好的。

请注意,我已经看到了这个这个。他们的标题中有相似的组成词,但没有回答这个特定的问题。

以下是否会导致严格的别名违规错误?或未定义的行为?

// some calling function
double a = 0.000234423;
func1(&a);

...

void func1(void *var)
{
    double a = *(double *)(var);
}
Run Code Online (Sandbox Code Playgroud)

438*_*427 8

指针的大小与其指向的元素的大小无关!

一个 4 字节的指针可以毫无问题地指向一个 8 字节或 32 字节或任何大小的元素。

我问是因为在我的机器上 sizeof(void *) 是 4,而 sizeof(double) 是 8,将一个转换为另一个似乎应该会导致问题

好吧,如果您确实将 4 字节指针强制转换为 8 字节双精度值,那将是一个大问题。但是,这不是您的代码所做的。

这是代码正在做的事情:

double a = * (double *)(var);
           | \--------------/
           |  This casts a void pointer to a double pointer
           |
           --> This dereferences the double pointer, i.e. reads the value of the pointed
               to element (aka the pointed to double)
Run Code Online (Sandbox Code Playgroud)

由于 void 指针是从 double 的地址创建的,因此将其强制转换回 double 指针是完全合法的,并且读取指向元素的值也是完全合法的。换句话说 - 在函数调用期间,您将双指针隐式转换为void 指针,并且在函数内部,void 指针被转换回双指针。完全合法的 C 代码。

通过额外的步骤,您的代码等效于:

void func1(void *var)
{
    double *pd = (double *)var;
    double a = *pd;
}
Run Code Online (Sandbox Code Playgroud)

这使它更清楚一点。