#include <stdint.h>
#include <iostream>
using namespace std;
uint32_t k[] = {0, 1, 17};
template <typename T>
bool f(T *data, int i) {
return data[0] < (T)(1 << k[i]);
}
int main() {
uint8_t v = 0;
cout << f(&v, 2) << endl;
cout << (0 < (uint8_t)(1 << 17)) << endl;
return 0;
}
g++ a.cpp && ./a.out
1
0
Why am I getting these results?
It gets assigned to the owner and the owner closes it. It's not usually difficult to persuade a tester to close mooted bugs. "It's a documentation issue." The owner should still be the one closing the bug so that they have the chance to ensure that the revised documentation correctly addresses the issue.
A software bug is an error, flaw, or fault in an application. This error causes the application to produce an unintended or unexpected result, such as crashing or producing invalid results. As software developers, we deal with software bugs all the time.
Example of a Bug Let's say that an eCommerce website has an Add to Cart button – as it is supposed to, However, when clicked, the button opens a window leading back to the product catalog, rather than the payment page as it should. This unpredictable and irrational behavior is a bug that needs to be fixed.
Glitches/bugs are software errors that can cause drastic problems within the code, and typically go unnoticed or unsolved during the production of said software. These errors can be game caused or otherwise exploited until a developer/development team repairs them with patches.
It looks like gcc reverses the shift and applies it to the other side, and I guess this is a bug.
In C (instead of C++) the same thing happens, and C translated to asm is easier to read, so I'm using C here; also I reduced the test cases (dropping templates and the k array). foo() is the original buggy f() function, foo1() is what foo() behaves like with gcc but shouldn't, and bar() shows what foo() should look like apart from the pointer read.
I'm on 64-bit, but 32-bit is the same apart from the parameter handling and finding k.
#include <stdint.h>
#include <stdio.h>
uint32_t k = 17;
char foo(uint8_t *data) {
return *data < (uint8_t)(1<<k);
/*
with gcc -O3 -S: (gcc version 4.7.2 (Debian 4.7.2-5))
movzbl (%rdi), %eax
movl k(%rip), %ecx
shrb %cl, %al
testb %al, %al
sete %al
ret
*/
}
char foo1(uint8_t *data) {
return (((uint32_t)*data) >> k) < 1;
/*
movzbl (%rdi), %eax
movl k(%rip), %ecx
shrl %cl, %eax
testl %eax, %eax
sete %al
ret
*/
}
char bar(uint8_t data) {
return data < (uint8_t)(1<<k);
/*
movl k(%rip), %ecx
movl $1, %eax
sall %cl, %eax
cmpb %al, %dil
setb %al
ret
*/
}
int main() {
uint8_t v = 0;
printf("All should be 0: %i %i %i\n", foo(&v), foo1(&v), bar(v));
return 0;
}
If your int
is 16-bit long, you're running into undefined behavior and either result is "OK".
Shifting N-bit integers by N or more bit positions left or right results in undefined behavior.
Since this happens with 32-bit ints, this is a bug in the compiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With