Tôi có một số mã giống như sau:
#include <bitset>
enum Flags { A = 1, B = 2, C = 3, D = 5,
E = 8, F = 13, G = 21, H,
I, J, K, L, M, N, O };
void apply_known_mask(std::bitset<64> &bits) {
const Flags important_bits[] = { B, D, E, H, K, M, L, O };
std::remove_reference<decltype(bits)>::type mask{};
for (const auto& bit : important_bits) {
mask.set(bit);
}
bits &= mask;
}
Clang> = 3.6 thực hiện điều thông minh và biên dịch nó thành một and
lệnh duy nhất (sau đó sẽ được nội tuyến ở mọi nơi khác):
apply_known_mask(std::bitset<64ul>&): # @apply_known_mask(std::bitset<64ul>&)
and qword ptr [rdi], 775946532
ret
Nhưng mọi phiên bản GCC tôi đã thử đều biên dịch điều này thành một mớ hỗn độn khổng lồ bao gồm xử lý lỗi mà lẽ ra phải là DCE'd tĩnh. Trong mã khác, nó thậm chí sẽ đặt important_bits
dữ liệu tương đương theo dòng với mã!
.LC0:
.string "bitset::set"
.LC1:
.string "%s: __position (which is %zu) >= _Nb (which is %zu)"
apply_known_mask(std::bitset<64ul>&):
sub rsp, 40
xor esi, esi
mov ecx, 2
movabs rax, 21474836482
mov QWORD PTR [rsp], rax
mov r8d, 1
movabs rax, 94489280520
mov QWORD PTR [rsp+8], rax
movabs rax, 115964117017
mov QWORD PTR [rsp+16], rax
movabs rax, 124554051610
mov QWORD PTR [rsp+24], rax
mov rax, rsp
jmp .L2
.L3:
mov edx, DWORD PTR [rax]
mov rcx, rdx
cmp edx, 63
ja .L7
.L2:
mov rdx, r8
add rax, 4
sal rdx, cl
lea rcx, [rsp+32]
or rsi, rdx
cmp rax, rcx
jne .L3
and QWORD PTR [rdi], rsi
add rsp, 40
ret
.L7:
mov ecx, 64
mov esi, OFFSET FLAT:.LC0
mov edi, OFFSET FLAT:.LC1
xor eax, eax
call std::__throw_out_of_range_fmt(char const*, ...)
Tôi nên viết mã này như thế nào để cả hai trình biên dịch đều có thể làm đúng? Không đạt được điều đó, tôi nên viết nó như thế nào để nó vẫn rõ ràng, nhanh chóng và có thể bảo trì được?
(1ULL << B) | ... | (1ULL << O)
(1ULL << Constant)
| trên mỗi dòng và căn chỉnh các tên không đổi trên các dòng khác nhau, điều đó sẽ dễ nhìn hơn.
int
kết quả của hoạt động chút CÓ THỂ int
HOẶC có thể được long long
tùy thuộc vào giá trị và về mặt hình thức enum
không tương đương với một int
hằng số. clang kêu gọi "như thể", gcc vẫn có âm thanh
B | D | E | ... | O
?