문제

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++.

도움이 되었습니까?

해결책

void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}

다른 팁

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));
}

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top