Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Возможно ли реализовать аналог функции Read из Паскаля? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Особенности Visual Studio 2010 http://www.cyberforum.ru/cpp-beginners/thread1241353.html
Всем привет. Вопрос знатокам С/C++. Мы знаем, что, взять например язык С: 1) Компилятор языка при присвоении одной переменной одного типа другой переменной другого типа, где возможна потеря...
C++ Не выводится на экран элемент динамического массива Здравствуйте! Сразу прошу прощения за название темы, т.к. далее по тексту вы узнаете, что проблема относится не совсем к выводу на экран элементов массива. А проблема заключается в следующем: ... http://www.cyberforum.ru/cpp-beginners/thread1241351.html
C++ Нужна программа, которая по регулярному выражению находит все совпадения в строке
Никак не могу освоить добавленную в C++11 библиотеку <regex>! Помогите пожалуйста! Нужна программа, которая по регулярному выражению находит все совпадения в строке (<string>), и, если не...
Формирование нечетных чисел C++
Приветствую всех! Имеется такой код: srand(time(0)); int ia,c=0; for(int i=0; i!=5; i++) { while(ia % 2 == 0) { ia = rand() % 100; }
C++ Классы: Не создаются объекты класса Apple http://www.cyberforum.ru/cpp-beginners/thread1241325.html
Includes.h #include <stdlib.h> #include <gl\glut.h> #include <math.h> #include<stdio.h> #include<time.h> #include<stdio.h> #include<iostream> using namespace std;
C++ Неправильно выводятся данные структуры #include <iostream> #include <conio.h> #include <string> #define deathgant 7 using namespace std; union tag_value{ int kill_1; int kill_2; подробнее

Показать сообщение отдельно
0x10
2474 / 1647 / 247
Регистрация: 24.11.2012
Сообщений: 4,068
15.08.2014, 19:33
Цитата Сообщение от 0x10 Посмотреть сообщение
На уровне ассемблера не покажу
Все-таки показать надо, чтобы не быть голословным. Из кода выше уберем все лишнее, чтобы было проще читать ассемблерный выхлоп. Итого останется:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void DummyFunction(int item);
 
template <class T>
void Read(T& item) {
    DummyFunction(item);
}
 
template <class T, class... Args>
void Read(T& item, Args&&... args) {
    Read(item);
    Read(args...);
}
 
int main() {
    int a, b, c, d;
    Read(a, b, c, d);
}
Сначала собираем без оптимизации:
g++ -std=c++11 -O0 -S main.cpp
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
    .file   "main.cpp"
    .text
    .globl  main
    .type   main, @function
main:
.LFB2:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    leaq    -4(%rbp), %rcx
    leaq    -8(%rbp), %rdx
    leaq    -12(%rbp), %rsi
    leaq    -16(%rbp), %rax
    movq    %rax, %rdi
    call    _Z4ReadIiIRiS0_S0_EEvRT_DpOT0_
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE2:
    .size   main, .-main
    .section    .text._Z4ReadIiIRiS0_S0_EEvRT_DpOT0_,"axG",@progbits,_Z4ReadIiIRiS0_S0_EEvRT_DpOT0_,comdat
    .weak   _Z4ReadIiIRiS0_S0_EEvRT_DpOT0_
    .type   _Z4ReadIiIRiS0_S0_EEvRT_DpOT0_, @function
_Z4ReadIiIRiS0_S0_EEvRT_DpOT0_:
.LFB3:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    %rcx, -32(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    _Z4ReadIiEvRT_
    movq    -32(%rbp), %rdx
    movq    -24(%rbp), %rcx
    movq    -16(%rbp), %rax
    movq    %rcx, %rsi
    movq    %rax, %rdi
    call    _Z4ReadIiIRiS0_EEvRT_DpOT0_
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE3:
    .size   _Z4ReadIiIRiS0_S0_EEvRT_DpOT0_, .-_Z4ReadIiIRiS0_S0_EEvRT_DpOT0_
    .weak   _Z4ReadIiJRiS0_S0_EEvRT_DpOT0_
    .set    _Z4ReadIiJRiS0_S0_EEvRT_DpOT0_,_Z4ReadIiIRiS0_S0_EEvRT_DpOT0_
    .section    .text._Z4ReadIiEvRT_,"axG",@progbits,_Z4ReadIiEvRT_,comdat
    .weak   _Z4ReadIiEvRT_
    .type   _Z4ReadIiEvRT_, @function
_Z4ReadIiEvRT_:
.LFB4:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    movl    %eax, %edi
    call    _Z13DummyFunctioni
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE4:
    .size   _Z4ReadIiEvRT_, .-_Z4ReadIiEvRT_
    .section    .text._Z4ReadIiIRiS0_EEvRT_DpOT0_,"axG",@progbits,_Z4ReadIiIRiS0_EEvRT_DpOT0_,comdat
    .weak   _Z4ReadIiIRiS0_EEvRT_DpOT0_
    .type   _Z4ReadIiIRiS0_EEvRT_DpOT0_, @function
_Z4ReadIiIRiS0_EEvRT_DpOT0_:
.LFB5:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    _Z4ReadIiEvRT_
    movq    -24(%rbp), %rdx
    movq    -16(%rbp), %rax
    movq    %rdx, %rsi
    movq    %rax, %rdi
    call    _Z4ReadIiIRiEEvRT_DpOT0_
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE5:
    .size   _Z4ReadIiIRiS0_EEvRT_DpOT0_, .-_Z4ReadIiIRiS0_EEvRT_DpOT0_
    .weak   _Z4ReadIiJRiS0_EEvRT_DpOT0_
    .set    _Z4ReadIiJRiS0_EEvRT_DpOT0_,_Z4ReadIiIRiS0_EEvRT_DpOT0_
    .section    .text._Z4ReadIiIRiEEvRT_DpOT0_,"axG",@progbits,_Z4ReadIiIRiEEvRT_DpOT0_,comdat
    .weak   _Z4ReadIiIRiEEvRT_DpOT0_
    .type   _Z4ReadIiIRiEEvRT_DpOT0_, @function
_Z4ReadIiIRiEEvRT_DpOT0_:
.LFB6:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    _Z4ReadIiEvRT_
    movq    -16(%rbp), %rax
    movq    %rax, %rdi
    call    _Z4ReadIiEvRT_
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE6:
    .size   _Z4ReadIiIRiEEvRT_DpOT0_, .-_Z4ReadIiIRiEEvRT_DpOT0_
    .weak   _Z4ReadIiJRiEEvRT_DpOT0_
    .set    _Z4ReadIiJRiEEvRT_DpOT0_,_Z4ReadIiIRiEEvRT_DpOT0_
    .ident  "GCC: (Ubuntu 4.9-20140406-1ubuntu1) 4.9.0 20140405 (experimental) [trunk revision 209157]"
    .section    .note.GNU-stack,"",@progbits

Разбирать весь код достаточно нудно, нам хватит заметить, что сгенерено несколько вариантов функции Read:
Код
$ cat main.s | grep Read | grep function
	.type	_Z4ReadIiIRiS0_S0_EEvRT_DpOT0_, @function
	.type	_Z4ReadIiEvRT_, @function
	.type	_Z4ReadIiIRiS0_EEvRT_DpOT0_, @function
	.type	_Z4ReadIiIRiEEvRT_DpOT0_, @function
И всего один вызов нашей заглушки DummyFunction - в 76 строке ассемблерного кода.
Первый уровень оптимизации:
g++ -std=c++11 -O1 -S main.cpp
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    .file   "main.cpp"
    .section    .text._Z4ReadIiEvRT_,"axG",@progbits,_Z4ReadIiEvRT_,comdat
    .weak   _Z4ReadIiEvRT_
    .type   _Z4ReadIiEvRT_, @function
_Z4ReadIiEvRT_:
.LFB4:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    (%rdi), %edi
    call    _Z13DummyFunctioni
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE4:
    .size   _Z4ReadIiEvRT_, .-_Z4ReadIiEvRT_
    .text
    .globl  main
    .type   main, @function
main:
.LFB2:
    .cfi_startproc
    subq    $24, %rsp
    .cfi_def_cfa_offset 32
    movq    %rsp, %rdi
    call    _Z4ReadIiEvRT_
    leaq    4(%rsp), %rdi
    call    _Z4ReadIiEvRT_
    leaq    8(%rsp), %rdi
    call    _Z4ReadIiEvRT_
    leaq    12(%rsp), %rdi
    call    _Z4ReadIiEvRT_
    movl    $0, %eax
    addq    $24, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE2:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.9-20140406-1ubuntu1) 4.9.0 20140405 (experimental) [trunk revision 209157]"
    .section    .note.GNU-stack,"",@progbits

У нас осталась одна функция Read, которая вызывается по одному разу для каждого аргумента. Уже тут нет рекурсивных вызовов. Если же использовать флаг -O2, то и эта функция будет заинлайнена:
g++ -std=c++11 -O2 -S main.cpp
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    .file   "main.cpp"
    .section    .text.unlikely,"ax",@progbits
.LCOLDB0:
    .section    .text.startup,"ax",@progbits
.LHOTB0:
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB2:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    xorl    %edi, %edi
    call    _Z13DummyFunctioni
    xorl    %edi, %edi
    call    _Z13DummyFunctioni
    xorl    %edi, %edi
    call    _Z13DummyFunctioni
    xorl    %edi, %edi
    call    _Z13DummyFunctioni
    xorl    %eax, %eax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE2:
    .size   main, .-main
    .section    .text.unlikely
.LCOLDE0:
    .section    .text.startup
.LHOTE0:
    .ident  "GCC: (Ubuntu 4.9-20140406-1ubuntu1) 4.9.0 20140405 (experimental) [trunk revision 209157]"
    .section    .note.GNU-stack,"",@progbits

Получено на компиляторе:
Код
$ g++ --version
g++ (Ubuntu 4.9-20140406-1ubuntu1) 4.9.0 20140405 (experimental) [trunk revision 209157]
2
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru