违反严格别名规则的强制转换

发布于 2024-09-24 12:45:19 字数 430 浏览 1 评论 0原文

我有一个函数需要一个 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++ 来完成。

I have a function that takes a unsigned long* and needs to pass it to a external library that takes a unsigned int* and on this platform unsigned int/long are the same size.

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

This generate a warning saying that its breaking strict-aliasing rules. Are there any work arounds?

Thank you

Edit: I apologize for not being clear. The code is an atomic update so going around the library to store it is not an option. I could drop down to assembly but I'd like to do this in C++.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰魂雪魄 2024-10-01 12:45:19
void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}
void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}
深空失忆 2024-10-01 12:45:19

这应该有效:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}

This should work:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}
海的爱人是光 2024-10-01 12:45:19

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

该标准的作者不想强迫实施者瞄准 intlong 之间的别名无法识别此类别名的平台。他们也不想编写适用于某些平台(别名可以发挥作用的平台)但不适用于其他平台(不适合别名的平台)的规则。相反,他们认为编写高质量编译器的人会在有用的情况下尝试识别别名。

能够使用指向一种 32 位类型的指针来读取和写入具有相同表示形式的另一种 32 位类型的值显然很有用,特别是当 API 根据其期望的类型进行拆分时。如果平台上的某些常见 API 使用 int* 表示 32 位值,而其他 API 使用 long*,则该 API 的质量通用实现平台必须允许使用另一种类型的指针来访问其中一种类型的数据。

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

Nothing in the C Standard mandates that int and long must have the same size; further, even if they do have the same size, nothing in the Standard mandates that they have the same representation (among other things, they could have incompatible combinations of padding bits and trap representations, such that aliasing between the two types could not serve any useful purpose).

The authors of the Standard did not want to force implementers targeting platforms where aliasing between int and long would serve no purpose to recognize such aliasing. They also did not want to write rules which would be applicable to some platforms (those where aliasing would serve a purpose) but not others (those where it wouldn't). Instead, they figured that people writing quality compilers would try to recognize aliasing in cases where it was useful.

Being able to use pointers to one 32-bit type to read and write values of another 32-bit type that has the same representation is clearly useful, especially if APIs are split as to which type they expect. If some commonplace APIs on a platform use int* for 32-bit values and others use long*, a quality general-purpose implementation for that platform must allow data of either type to be accessed using pointers of the other.

Unfortunately, however, the authors of some compilers are more interested in processing a certain subset of programs quickly, than in processing a larger subset of programs usefully, and cannot be relied upon to generate useful code if it's necessary to exchange data between APIs that use the same data representation but different named types unless one completely disables aliasing analysis. Of course, if one is targeting dialects of C that are suitable for general-purpose use on microcontrollers, such issues don't matter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文