Не могу не поделиться.
Как Вы думаете, что выведет в stdout следующий код в случае MSVC-11.0?
#include <cstdio>
#include <iostream>
class Foo
{
public:
float getFloat(int value)
{
switch (value)
{
case 1:
std::printf("1 \n");
return 0.5F;
case 0:
std::printf("0 \n");
return 1.0F;
case 2:
std::printf("2 \n");
return 2.0F;
case 3:
std::printf("3 \n");
return 3.0F;
case 4:
std::printf("4 \n");
return 4.0F;
}
return 1.0F;
}
};
int main()
{
Foo instance;
std::cout << instance.getFloat(3) << '\n';
}
|
От: |
dilmah
|
|
Дата: | 14.02.13 19:17 |
|
Оценка: |
-1
|
NT>Как Вы думаете, что выведет в stdout следующий код в случае MSVC-11.0?
почему это должно быть интересно?
есть sync_with_stdio чтобы это работало правильно.
Re[2]: MSVC-11.0 - вопрос
D>почему это должно быть интересно?
D>есть sync_with_stdio чтобы это работало правильно.
А если ещё подумать? Неужели я бы стал спрашивать Вас о таком?
Re[3]: MSVC-11.0 - вопрос
|
От: |
dilmah
|
|
Дата: | 14.02.13 19:50 |
|
Оценка: |
|
ну не томи, не у всех же есть MSVC
Re[4]: MSVC-11.0 - вопрос
D>ну не томи, не у всех же есть MSVC
Пусть остальные посмотрят, не хочу рассказывать раньше времени.
Re[5]: MSVC-11.0 - вопрос
|
От: |
Alca
|
|
Дата: | 14.02.13 20:02 |
|
Оценка: |
-1
|
Здравствуйте, Nikita.Trophimov, Вы писали:
D>>ну не томи, не у всех же есть MSVC
NT>Пусть остальные посмотрят, не хочу рассказывать раньше времени.
Ты, что троль??
ВЫвод: 3 3
Раз уж понеслись минусы без пояснений (молодцы, однако), то привожу ответ:
Debug
3
3
Release
3
0
|
От: |
uzhas
|
|
Дата: | 14.02.13 20:07 |
|
Оценка: |
|
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>Не могу не поделиться.
все же смог
Re[2]: MSVC-11.0 - вопрос
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>Раз уж понеслись минусы без пояснений (молодцы, однако)
А тебя какая разница? Минусы, плюсы?
Ты вообще <b>НИ ОДНОЙ</b> оценки никому не поставил.
Re[3]: MSVC-11.0 - вопрос
Сказать не легче?
Re[4]: MSVC-11.0 - вопрос
|
От: |
Piko
|
|
Дата: | 14.02.13 20:14 |
|
Оценка: |
|
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>Сказать не легче?
Что? Кому?
Re[5]: MSVC-11.0 - вопрос
P>Что? Кому?
Вы как в дет. саде... Мне. То, что не нравится / с чем не согласны.
Re[2]: MSVC-11.0 - вопрос
|
От: |
Piko
|
|
Дата: | 14.02.13 20:20 |
|
Оценка: |
|
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>https://connect.microsoft.com/VisualStudio/feedback/details/779043/c-switch-statement-broken-in-release-build#details
там по ссылке:
#include <stdio.h>
#include <tchar.h>
float GetFloat(int nInt)
{
printf("%s", "GetFloat() - entered\n");
switch (nInt)
{
case 1 :
printf("%s", "GetFloat() - case 1 entered\n");
return 0.5F;
case 0 :
printf("%s", "GetFloat() - case 0 entered\n");
return 1.0F;
case 2 :
printf("%s", "GetFloat() - case 2 entered\n");
return 2.0F;
case 3 :
printf("%s", "GetFloat() - case 3 entered\n");
return 3.0F;
case 4 :
printf("%s", "GetFloat() - case 4 entered\n");
return 4.0F;
}
printf("%s", "GetFloat() - exit\n");
return 1.0F;
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("fValue = %2.2f\n", GetFloat(3));
return 0;
}
Теперь ясно откуда эти "getFloat" растут.
Почему бы сразу было не сказать в чём дело?
Re[3]: MSVC-11.0 - вопрос
P>Теперь ясно откуда эти "getFloat" растут.
Ну да, я ничего себе не присваиваю. Ссылки приведены.
P>Почему бы сразу было не сказать в чём дело?
Очевидно же — чтобы подогреть интерес к обсуждаемой теме. Вам, как я вижу, это наоборот не понравилось, так что извиняюсь.
Re[2]: MSVC-11.0 - вопрос
|
От: |
rusted
|
|
Дата: | 14.02.13 20:49 |
|
Оценка: |
|
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>Ссылка на StackOverflow:
NT>http://stackoverflow.com/questions/14835262/is-it-now-wrong-to-return-from-a-switch-statement-in-c11
Посмотрел asm вывод: баг есть только при /arch:SSE2, getFloat возвращает результат в FPU, а main получается вот таким:
; 27 : {
mov ecx, 3
call ?getFloat@@YAMH@Z ; getFloat
; 28 : printf( "%f\n", getFloat( 3 ) );
cvtss2sd xmm0, xmm0
sub esp, 8
movsd QWORD PTR [esp], xmm0
push OFFSET ??_C@_03PPOCCAPH@?$CFf?6?$AA@
call _printf
add esp, 12 ; 0000000cH
; 29 : }
т.е. ожидает результат getFloat в xmm0.
Если компилить с /arch:SSE, то всё нормально:
; 27 : {
push ebp
mov ebp, esp
push ecx
mov ecx, 3
call ?getFloat@@YAMH@Z ; getFloat
fstp DWORD PTR $T1[ebp]
; 28 : printf( "%f\n", getFloat( 3 ) );
fld DWORD PTR $T1[ebp]
sub esp, 8
fstp QWORD PTR [esp]
push OFFSET ??_C@_03PPOCCAPH@?$CFf?6?$AA@
call _printf
add esp, 12 ; 0000000cH
; 29 : }
Re[2]: MSVC-11.0 - вопрос
|
От: |
Шахтер
|
|
Дата: | 14.02.13 20:52 |
|
Оценка: |
|
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>https://connect.microsoft.com/VisualStudio/feedback/details/779043/c-switch-statement-broken-in-release-build#details
Я глянул ассемблерный листинг.
Сама функция getFloat() сгенерирована правильно. Но вот дальше что-то странное.
mov ecx, 3
call ?getFloat@Foo@@QAEMH@Z ; Foo::getFloat
; 35 : Foo instance;
; 36 : std::cout << instance.getFloat(3) << '\n';
push ecx
mov ecx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
movss DWORD PTR [esp], xmm0
call DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@M@Z
mov ecx, eax
call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@D@Z ; std::operator<<<std::char_traits<char> >
Короче, похоже, нарушены соглашения по вызовам.
getFloat() грузит результат на вершину FP стека, а вызывающая функция забирает результат из xmm0.
В XXI век с
CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: MSVC-11.0 - вопрос
Более того, судя по StackOverflow, результат также будет зависить от уровня оптимизации и 64-битного режима.
Re[3]: MSVC-11.0 - вопрос
Ш>Я глянул ассемблерный листинг.
Ш>Сама функция getFloat() сгенерирована правильно. Но вот дальше что-то странное.
Да, на StackOverflow уже обсуждали асм листинг. Блин, этот баг действительно тяжело ловить...
Пока на собственное сообщение не было ответов, его можно удалить.