Из GDB вы ничего не можете сделать, потому что он просто следует отладочной информации, генерируемой компилятором.Вы можете увидеть вывод сборки с помощью gcc -g -S -fverbose-asm -fno-dwarf2-cfi-asm -o - main.c
.Благодаря аннотациям вы сможете получить суть этого, даже если вы не знаете ассемблер.
Вот выдержка:
# main.c:4: int dd = ( (aa + 3 - 1)
movl -4(%rbp), %eax # aa, tmp91
addl $2, %eax #, _1
# main.c:5: / bb)
cltd
idivl -8(%rbp) # bb
movl %eax, %edx # tmp92, _2
# main.c:4: int dd = ( (aa + 3 - 1)
movl -12(%rbp), %eax # cc, tmp94
movl %eax, %ecx # tmp94, tmp99
sall %cl, %edx # tmp99, _2
movl %edx, %eax # _2, tmp95
movl %eax, -16(%rbp) # tmp95, dd
Последний блок эквивалентен
int dd = _2 << cc;
Поскольку результат операции должен где-то храниться, сдвиг и присвоение не разделяются.Ссылка на строку, содержащую присвоение.
Вы должны переписать код, чтобы иметь одну операцию на оператор:
int t1 = (aa + 3 - 1);
int t2 = t1 / bb;
int dd = t2 << cc;
Вот соответствующая сборка:
# main.c:4: int t1 = (aa + 3 - 1);
movl -4(%rbp), %eax # aa, tmp92
addl $2, %eax #, tmp91
movl %eax, -16(%rbp) # tmp91, t1
# main.c:5: int t2 = t1 / bb;
movl -16(%rbp), %eax # t1, tmp96
cltd
idivl -8(%rbp) # bb
movl %eax, -20(%rbp) # tmp94, t2
# main.c:6: int dd = t2 << cc;
movl -12(%rbp), %eax # cc, tmp100
movl -20(%rbp), %edx # t2, tmp102
movl %eax, %ecx # tmp100, tmp106
sall %cl, %edx # tmp106, tmp102
movl %edx, %eax # tmp102, tmp101
movl %eax, -24(%rbp) # tmp101, dd
По сути, это то же самое, что и раньше, но теперь блоки идеально соответствуют операторам.Вы не можете контролировать вывод компилятора, но он попытается сохранить границы между операторами, так что это ваш лучший вариант.