-
Notifications
You must be signed in to change notification settings - Fork 397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compatibility with gcc 4.9 #46
Comments
Okay, I figured out what's going on. In the generated header for one of our LCM message types, the
For reference, the Python version (which matches Java), looks like this:
The problem is that for my particular message types, it happens that, in C++, the value of C++:
Python:
But when right-shifting, the C++ behavior is different: C++:
Python:
I believe this is due to the fact that the behavior of a right-shift of a negative integer in C++ is undefined (see page 85 of http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1336.pdf ). The result of this is that certain LCM message types generate incorrect fingerprints in C++, at least on some platforms and compilers. |
Disabling compiler optimizations (with -O0) results in the correct hash value in C++ (that is, the value matches the one from Python and Java). It would appear that newer versions of g++ are relying on the undefined nature of right-shift of negative numbers and producing different answers depending on the optimization level. |
It's also difficult to produce a minimal example that demonstrates the problem, because g++ really does produce different hash values depending on what optimizations it chooses to make. The simplest possible code: int64_t hash = -7697761889842642409LL;
std::cout << "hash: " << hash << std::endl;
std::cout << ((hash >> 63)&1) << std::endl; always results in the output:
regardless of optimization level. But somehow with the -O3 flag present, g++ produces a different result for |
Okay, here's the simplest example I can find that demonstrates that the issue is real, and the behavior from g++ 4.8 is different from 4.9: My code: #include <iostream>
#include <lcm/lcm_coretypes.h>
int64_t sub_hash() {
int64_t hash = 0;
for (int64_t i=0; i < 5486218109915584133; i++) {
hash++;
}
return hash;
}
int main(int argc, char** argv) {
int64_t hash = 0x4909180abc8e6b92LL + sub_hash();
std::cout << "hash: " << hash << std::endl;
std::cout << "((hash >> 63)&1): " << ((hash >> 63)&1) << std::endl;
return 0;
} Note that the code uses a truly insane loop in order to force g++ to do some optimization magic. Results: gcc 4.8:
gcc 4.9
|
Hi all, Thanks for the report. Do you know if this is related to this pull request #31? Albert |
Ah, yes, looks like exactly the same issue. We've been on an older LCM release, so we haven't gotten that fix. |
Ok, thanks. Closing this since I believe the issue to be already resolved |
@rdeits reports this issue over on the Drake project. Cross posting here for visibility.
RobotLocomotion/drake#1663
Perhaps we can write a minimal c++ program that demonstrates the issue.
The text was updated successfully, but these errors were encountered: