我有一个带有无符号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 ++中这样做。答案 0 :(得分:8)
void UpdateVar(unsigned long* var) {
unsigned int x = static_cast<unsigned int>(*var);
ExternalLibUpdateVar(&x);
*var = static_cast<unsigned long>(x);
}
答案 1 :(得分:2)
这应该有效:
void UpdateVar(unsigned long* var) {
// this function will change the value at the address of var
ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}
答案 2 :(得分:1)
C标准中没有规定int
和long
必须具有相同的尺寸;此外,即使它们确实具有相同的大小,标准中没有任何内容要求它们具有相同的表示形式(除此之外,它们可能具有填充位和陷阱表示的不兼容组合,使得两种类型之间的混叠不能用于任何有用的目的)。
标准的作者不希望强制实施者针对平台,int
和long
之间的别名无法识别此类别名。他们也不想编写适用于某些平台的规则(别名可用于某些目的的规则),而不是其他平台(那些不会用于其他平台的规则)。相反,他们认为编写高质量编译器的人会尝试在有用的情况下识别别名。
能够使用指向一个32位类型的指针来读取和写入具有相同表示的另一个32位类型的值显然是有用的,特别是如果API被分割为它们期望的类型。如果平台上的某些普通API使用int*
表示32位值而其他API使用long*
,则该平台的 quality 通用实现必须允许任何一种类型的数据可以使用另一个指针访问。