6

我有一个函数需要一个 unsigned long* 并且需要将它传递给一个采用 unsigned int* 的外部库,并且在这个平台上 unsigned int/long 的大小相同。

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable
}

这会产生一个警告,说它违反了严格的别名规则。有解决办法吗?

谢谢

编辑:我很抱歉不清楚。该代码是一个原子更新,所以绕过库来存储它不是一种选择。我可以下到汇编,但我想在 C++ 中执行此操作。

4

3 回答 3

8
void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}
于 2010-09-21T19:44:14.280 回答
2

这应该有效:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}
于 2010-09-21T19:43:40.497 回答
1

C 标准中没有任何内容要求int并且long必须具有相同的大小;此外,即使它们确实具有相同的大小,标准中也没有任何规定要求它们具有相同的表示形式(除此之外,它们可能具有不兼容的填充位和陷阱表示组合,因此这两种类型之间的别名无法提供任何有用的目的)。

该标准的作者不想强迫实现者针对存在别名的平台,int并且long没有任何目的来识别这种别名。他们也不想编写适用于某些平台(别名将服务于目的的平台)但不适用于其他平台(不适用的平台)的规则。相反,他们认为编写高质量编译器的人会在有用的情况下尝试识别别名。

能够使用指向一种 32 位类型的指针来读取和写入具有相同表示的另一种 32 位类型的值显然很有用,尤其是当 API 被拆分为它们期望的类型时。如果平台上的一些普通 API 使用int*32 位值而其他API 使用long*,则该平台的高质量通用实现必须允许使用另一种类型的指针访问任何一种类型的数据。

然而不幸的是,一些编译器的作者更感兴趣的是快速处理某个程序子集,而不是有用地处理更大的程序子集,并且如果需要在使用的 API 之间交换数据,则不能依赖它来生成有用的代码相同的数据表示,但不同的命名类型,除非完全禁用别名分析。当然,如果一个人的目标是适合在微控制器上通用使用的 C 语言方言,那么这些问题就无关紧要了。

于 2016-08-19T20:19:49.143 回答