ITNOA
Я хочу использовать псевдонимы переменных в C ++, чтобы сделать код меньше, чем раньше, без каких-либо затрат (нулевая стоимость), так как я могу лучше описать свою цель, см. Подробности ниже
У меня есть структура, как показано ниже
struct Info
{
size_t d1;
size_t d2;
size_t d3;
size_t d4;
};
Я использую эту структуру в другом классе. (этот вызов LargeName
class), как показано ниже
class LargeName
{
public:
// … many fields and methods
Info get_large_name_info() const
{
return info;
}
private:
Info info;
}
В этом сценарии, если я хочу использовать информационные поля из LargeName
Instant во внешней функции, мне нужно что-то вроде ниже
void foo(LargeName large_name)
{
large_name.get_large_name_info().d1;
large_name.get_large_name_info().d2;
large_name.get_large_name_info().d3;
large_name.get_large_name_info().d4;
}
Как вы можете видеть в приведенном выше примере, если мое имя класса и имя доступа к получателю информации слишком длинное, мне нужно написать очень символ, чтобы использовать от d1 до d4. Но я хочу их избегать. так, например, я могу написать код ниже, чтобы предотвратить это
void foo(LargeName large_name)
{
const Info& info = large_name.get_large_name_info();
info.d1;
info.d2;
info.d3;
info.d4;
}
Как вы можете видеть, мой код немного чище и намного короче, чем раньше. (Я назвал info
is псевдоним переменной для large_name.get_large_name_info()
) Но проблема в том, что я не уверен, что компилятор сгенерирует такой же код для новой версии моего кода, как и раньше.
Я думаю, что вторая реализация foo - моя ссылка на оплату и стоимость разыменования для использования переменной info.
У меня два вопроса:
Первый вопрос - как изменить псевдонимы в C ++ без каких-либо затрат?
Примечание: Версия сборки двух функций foo
отличается. Я проверяю G CC версии 5.4.0 с переключателем -std=c++11 -O3 -S
.
Второй вопрос: , почему компилятор генерирует другой код для этого метода foo
? в какой ситуации эти два кода (первый foo
и второй foo
) не ведут себя точно так же (я хочу узнать, почему компилятор генерирует другой код?)? (Я думаю, что если два кода точно такие же, то сгенерированная сборка должна быть одинаковой)
-------------------- ПРИЛОЖЕНИЕ ------ -------------
Полный пример:
Исходный код:
#include <cstdlib>
#include <iostream>
#include <array>
using namespace std;
class A
{
public:
int id;
std::array<size_t, 4> data;
float prec;
};
class User
{
public:
A get_a() const
{
return a;
}
private:
A a;
};
int main()
{
User user;
// scenario 1
#ifdef SC1
cout << "A id: " << user.get_a().id << endl;
cout << "A prec: " << user.get_a().prec << endl;
cout << "A data: ";
cout << user.get_a().data[0];
cout << user.get_a().data[1];
cout << user.get_a().data[2];
cout << user.get_a().data[3];
cout << endl;
#endif
// scenario 2
#ifdef SC2
const A& a = user.get_a();
cout << "A id: " << a.id << endl;
cout << "A prec: " << a.prec << endl;
cout << "A data: ";
cout << a.data[0];
cout << a.data[1];
cout << a.data[2];
cout << a.data[3];
cout << endl;
#endif
return EXIT_SUCCESS;
}
скомпилировать с g++ -std=c++11 -O3 -D=SC1 -S main.cpp
сценарий 1:
.file "main.cpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "A id: "
.LC1:
.string "A prec: "
.LC2:
.string "A data: "
.section .text.unlikely,"ax",@progbits
.LCOLDB3:
.section .text.startup,"ax",@progbits
.LHOTB3:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB1495:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movl $6, %edx
movl $.LC0, %esi
movl $_ZSt4cout, %edi
subq $80, %rsp
.cfi_def_cfa_offset 96
movl 16(%rsp), %ebx
movq %fs:40, %rax
movq %rax, 72(%rsp)
xorl %eax, %eax
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
movl %ebx, %esi
movl $_ZSt4cout, %edi
call _ZNSolsEi
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movss 56(%rsp), %xmm1
movl $8, %edx
movl $.LC1, %esi
movl $_ZSt4cout, %edi
movss %xmm1, 12(%rsp)
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
pxor %xmm0, %xmm0
movl $_ZSt4cout, %edi
cvtss2sd 12(%rsp), %xmm0
call _ZNSo9_M_insertIdEERSoT_
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movl $.LC2, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movq 24(%rsp), %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movq 32(%rsp), %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movq 40(%rsp), %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movq 48(%rsp), %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movl $_ZSt4cout, %edi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movq 72(%rsp), %rcx
xorq %fs:40, %rcx
jne .L5
addq $80, %rsp
.cfi_remember_state
.cfi_def_cfa_offset 16
xorl %eax, %eax
popq %rbx
.cfi_def_cfa_offset 8
ret
.L5:
.cfi_restore_state
call __stack_chk_fail
.cfi_endproc
.LFE1495:
.size main, .-main
.section .text.unlikely
.LCOLDE3:
.section .text.startup
.LHOTE3:
.section .text.unlikely
.LCOLDB4:
.section .text.startup
.LHOTB4:
.p2align 4,,15
.type _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB1689:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
addq $8, %rsp
.cfi_def_cfa_offset 8
jmp __cxa_atexit
.cfi_endproc
.LFE1689:
.size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section .text.unlikely
.LCOLDE4:
.section .text.startup
.LHOTE4:
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I_main
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.hidden __dso_handle
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
компилировать с g++ -std=c++11 -O3 -D=SC2 -S main.cpp
Сценарий 2:
.file "main.cpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "A id: "
.LC1:
.string "A prec: "
.LC2:
.string "A data: "
.section .text.unlikely,"ax",@progbits
.LCOLDB3:
.section .text.startup,"ax",@progbits
.LHOTB3:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB1495:
.cfi_startproc
pushq %r14
.cfi_def_cfa_offset 16
.cfi_offset 14, -16
pushq %r13
.cfi_def_cfa_offset 24
.cfi_offset 13, -24
movl $6, %edx
pushq %r12
.cfi_def_cfa_offset 32
.cfi_offset 12, -32
pushq %rbp
.cfi_def_cfa_offset 40
.cfi_offset 6, -40
movl $.LC0, %esi
pushq %rbx
.cfi_def_cfa_offset 48
.cfi_offset 3, -48
movl $_ZSt4cout, %edi
subq $80, %rsp
.cfi_def_cfa_offset 128
movl 16(%rsp), %r14d
movss 56(%rsp), %xmm1
movss %xmm1, 12(%rsp)
movq 24(%rsp), %r13
movq 32(%rsp), %r12
movq %fs:40, %rax
movq %rax, 72(%rsp)
xorl %eax, %eax
movq 40(%rsp), %rbp
movq 48(%rsp), %rbx
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
movl %r14d, %esi
movl $_ZSt4cout, %edi
call _ZNSolsEi
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movl $8, %edx
movl $.LC1, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
pxor %xmm0, %xmm0
movl $_ZSt4cout, %edi
cvtss2sd 12(%rsp), %xmm0
call _ZNSo9_M_insertIdEERSoT_
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movl $.LC2, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movq %r13, %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movq %r12, %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movq %rbp, %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movq %rbx, %rsi
movl $_ZSt4cout, %edi
call _ZNSo9_M_insertImEERSoT_
movl $_ZSt4cout, %edi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movq 72(%rsp), %rcx
xorq %fs:40, %rcx
jne .L5
addq $80, %rsp
.cfi_remember_state
.cfi_def_cfa_offset 48
xorl %eax, %eax
popq %rbx
.cfi_def_cfa_offset 40
popq %rbp
.cfi_def_cfa_offset 32
popq %r12
.cfi_def_cfa_offset 24
popq %r13
.cfi_def_cfa_offset 16
popq %r14
.cfi_def_cfa_offset 8
ret
.L5:
.cfi_restore_state
call __stack_chk_fail
.cfi_endproc
.LFE1495:
.size main, .-main
.section .text.unlikely
.LCOLDE3:
.section .text.startup
.LHOTE3:
.section .text.unlikely
.LCOLDB4:
.section .text.startup
.LHOTB4:
.p2align 4,,15
.type _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB1689:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
addq $8, %rsp
.cfi_def_cfa_offset 8
jmp __cxa_atexit
.cfi_endproc
.LFE1689:
.size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section .text.unlikely
.LCOLDE4:
.section .text.startup
.LHOTE4:
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I_main
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.hidden __dso_handle
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
И разница:
19c19
< pushq %rbx
---
> pushq %r14
21c21,24
< .cfi_offset 3, -16
---
> .cfi_offset 14, -16
> pushq %r13
> .cfi_def_cfa_offset 24
> .cfi_offset 13, -24
22a26,31
> pushq %r12
> .cfi_def_cfa_offset 32
> .cfi_offset 12, -32
> pushq %rbp
> .cfi_def_cfa_offset 40
> .cfi_offset 6, -40
23a33,35
> pushq %rbx
> .cfi_def_cfa_offset 48
> .cfi_offset 3, -48
26,27c38,43
< .cfi_def_cfa_offset 96
< movl 16(%rsp), %ebx
---
> .cfi_def_cfa_offset 128
> movl 16(%rsp), %r14d
> movss 56(%rsp), %xmm1
> movss %xmm1, 12(%rsp)
> movq 24(%rsp), %r13
> movq 32(%rsp), %r12
30a47,48
> movq 40(%rsp), %rbp
> movq 48(%rsp), %rbx
32c50
< movl %ebx, %esi
---
> movl %r14d, %esi
37d54
< movss 56(%rsp), %xmm1
41d57
< movss %xmm1, 12(%rsp)
52c68
< movq 24(%rsp), %rsi
---
> movq %r13, %rsi
55c71
< movq 32(%rsp), %rsi
---
> movq %r12, %rsi
58c74
< movq 40(%rsp), %rsi
---
> movq %rbp, %rsi
61c77
< movq 48(%rsp), %rsi
---
> movq %rbx, %rsi
71c87
< .cfi_def_cfa_offset 16
---
> .cfi_def_cfa_offset 48
73a90,97
> .cfi_def_cfa_offset 40
> popq %rbp
> .cfi_def_cfa_offset 32
> popq %r12
> .cfi_def_cfa_offset 24
> popq %r13
> .cfi_def_cfa_offset 16
> popq %r14