Visual Studio 2010 (Express) работает, по крайней мере, в простых случаях, которые я тестировал. Кто-нибудь, чтобы проверить gcc?
Я проверял следующее:
1. Проезжает только i
:
int vars[] = {1,2,3,12,3,23,1,213,231,1,21,12,213,21321,213,123213,213123};
int ok1(const int i){
return sqrtl(vars[i]);
}
int ok2(const int & i){
return sqrtl(vars[i]);
}
void main() {
int i;
std::cin >> i;
//i = ok1(i);
i = ok2(i);
std::cout << i;
}
ASM:
i = ok1(i);
000D1014 mov ecx,dword ptr [i]
000D1017 fild dword ptr vars (0D3018h)[ecx*4]
000D101E call _CIsqrt (0D1830h)
000D1023 call _ftol2_sse (0D1840h)
i = ok2(i);
013A1014 mov ecx,dword ptr [i]
013A1017 fild dword ptr vars (13A3018h)[ecx*4]
013A101E call _CIsqrt (13A1830h)
013A1023 call _ftol2_sse (13A1840h)
Что ж, ASM идентичны, без сомнения, была проведена оптимизация.
2. Проходя i
и &i
:
Давайте рассмотрим ансер @newacct здесь.
int vars[] = {1,2,3,12,3,23,1,213,231,1,21,12,213,21321,213,123213,213123};
int ok1(const int i, int * pi) {
*pi = 2;
return sqrtl(vars[i]);
}
int ok2(const int & i, int * pi) {
*pi = 2;
return sqrtl(vars[i]);
}
void main() {
int i;
int * pi = &i;
std::cin >> i;
i = ok1(i, pi);
//i = ok2(i, pi);
std::cout << i;
}
ASM:
i = ok1(i, pi);
00891014 mov ecx,dword ptr [i]
00891017 fild dword ptr vars (893018h)[ecx*4] // access vars[i]
0089101E call _CIsqrt (891830h)
00891023 call _ftol2_sse (891840h)
i = ok2(i, pi);
011B1014 fild dword ptr [vars+8 (11B3020h)] // access vars[2]
011B101A call _CIsqrt (11B1830h)
011B101F call _ftol2_sse (11B1840h)
В ok1
Я не вижу записи 2 * в pi
. Вероятно, он понимает, что область памяти в любом случае будет перезаписана результатом функции, поэтому запись бесполезна.
С ok2
компилятор настолько умный, насколько я ожидал. Он понимает, что i
и pi
указывают на одно и то же место, поэтому он использует жестко 2
напрямую.
Примечания:
- Я скомпилировал два раза для обоих тестов, один раз раскомментировав только
ok1
, один раз раскомментировав только ok2
. Компиляция обоих одновременно приводит к более сложной оптимизации между двумя функциями, которые в конечном итоге все встраиваются и смешиваются
- Я добавил поиск в массиве
vars
, потому что простые вызовы sqrtl
были упрощены до базовых ADD- и MUL-подобных операций без фактического вызова
- Скомпилировано в выпуске
- Дали ожидаемые результаты, конечно же