Aşağı yukarı bunun gibi bir kodum var:
#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 akıllıca bir şey yapar ve bunu tek bir and
talimatta derler (daha sonra her yerde satır içi olur):
apply_known_mask(std::bitset<64ul>&): # @apply_known_mask(std::bitset<64ul>&)
and qword ptr [rdi], 775946532
ret
Ancak denediğim her GCC sürümü, bunu statik olarak DCE olması gereken hata işlemeyi içeren muazzam bir karmaşaya derliyor. Diğer kodda, important_bits
muadili veri olarak kodla aynı hizaya bile yerleştirecektir !
.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*, ...)
Her iki derleyicinin de doğru şeyi yapabilmesi için bu kodu nasıl yazmalıyım? Aksi takdirde, açık, hızlı ve sürdürülebilir kalması için bunu nasıl yazmalıyım?
(1ULL << B) | ... | (1ULL << O)
(1ULL << Constant)
| her satırda ve sabit isimleri farklı satırlarda hizalayın, bu gözler için daha kolay olacaktır.
int
sonucu, bit işleminin bir sonucudur int
VEYA long long
değere bağlı olabilir ve resmi enum
olarak bir int
sabite eşdeğer değildir . clang "sanki" anlamına gelir, gcc bilgiçlik taslamaz
B | D | E | ... | O
mısınız?