Tôi thấy hành vi mà tôi không mong đợi khi biên dịch mã này với các mức tối ưu hóa khác nhau trong gcc.Mức tối ưu hóa trong hành vi thay đổi chương trình ccc gcc
Kiểm tra chức năng phải điền số nguyên không dấu 64 bit với số nguyên, dịch chuyển bit shift_size sang trái và trả lại 32 bit thấp dưới dạng số nguyên không dấu 32 bit.
Khi tôi biên dịch với -O0 tôi nhận được kết quả mong đợi.
Khi tôi biên dịch với -O2 Tôi không, nếu tôi cố gắng dịch chuyển 32 bit trở lên. Trong thực tế, tôi nhận được chính xác kết quả tôi mong đợi nếu tôi đang chuyển số nguyên 32 bit bằng các thay đổi lớn hơn hoặc bằng chiều rộng bit trên x86, đó là một sự thay đổi chỉ sử dụng 5 bit thấp của kích thước thay đổi .
Nhưng tôi đang chuyển số 64 bit, vì vậy, thay đổi < 64 phải hợp pháp?
Tôi cho rằng đó là lỗi trong sự hiểu biết của tôi chứ không phải trong trình biên dịch, nhưng tôi đã không thể đoán được.
máy của tôi: gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 i686-linux-gnu
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
uint32_t test(unsigned int shift_size) {
uint64_t res = 0;
res = ~res;
res = res << shift_size; //Shift size < uint64_t width so this should work
return res; //Implicit cast to uint32_t
}
int main(int argc, char *argv[])
{
int dst;
sscanf(argv[1], "%d", &dst); //Get arg from outside so optimizer doesn't eat everything
printf("%" PRIu32 "l\n", test(dst));
return 0;
}
Cách sử dụng:
$ gcc -Wall -O0 test.c
$ ./a.out 32
0l
$ gcc -Wall -O2 test.c
$ ./a.out 32
4294967295l
Bạn cũng có thể đăng các phần liên quan của mã lắp ráp do trình biên dịch của bạn tạo ra không? ('-S' cho gcc) –
FWIW nó cho kết quả chính xác (' 0l') cho tôi trên tất cả các mức tối ưu từ '-O0' đến' -O3' bằng gcc 4.2.1, vì vậy tôi nghi ngờ bạn * có thể * có tìm thấy lỗi gcc. –
hm, mã hoạt động tốt ở cả hai mức tối ưu cho tôi ... (gcc version 4.5.0 20100604, openSUSE 11.3 (x86_64)) – Bort