Трабла с VC или так должно

Тема в разделе "LANGS.C", создана пользователем SWR, 26 фев 2008.

  1. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    Вот код:
    UCHAR p1 = 7;
    UCHAR p2 = 8;
    UINT p = p1 - p2;

    После выполнения в p UINT(-1).

    Но p1 - p2 должно быть равно 255, и приравнивание к UINT недолжно приводить к расширению знака.
    Вопрос:
    Это так задумано или опять выпендреж мелкомагких.
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    UINT p = p1 - p2 == (UINT)p1 - (UINT)p2
     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    IceStudent

    А вот и не так! Гы-гы-гы )))
     
  4. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    НУ
    float p1 = 9.1;
    float p2 = 8.5;
    UINT p = p1 - p2;

    тут p равно 0

    если как ты предлагаеш
    UINT p = p1 - p2 == (UINT)p1 - (UINT)p2
    то должно 1
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    а как оно его откомпилировало? покажи кодес
     
  6. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    Ну как и ожидалось,
    00402718 mov byte ptr [ebp-1],7
    0040271C mov byte ptr [ebp-2],8
    00402720 xor eax,eax
    00402722 mov al,byte ptr [ebp-1]
    00402725 xor ecx,ecx
    00402727 mov cl,byte ptr [ebp-2]
    0040272A sub eax,ecx
    0040272C mov dword ptr [ebp-8],eax

    P.S. в релизе обращение к стеку кратные 4 (выровнены), мож кто обьяснит зачем такой изврат в дебаге (byte ptr [ebp-1],7)
     
  7. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    ИМХО:
    пункт 4.5

    An rvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13)
    is less than the rank of int can be converted to an rvalue of type int if int can represent all the values of the source
    type; otherwise, the source rvalue can be converted to an rvalue of type unsigned int.
     
  8. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Код (Text):
    1. #include <iostream>
    2.  
    3. template <class T>
    4. void f(T)
    5. {
    6.     std::cout << typeid(T).name() << std::endl;
    7. }
    8.  
    9. int main()
    10. {
    11.     unsigned char p1 = 7;
    12.     unsigned char p2 = 8;
    13.  
    14.     f(p1 - p2);
    15.  
    16.     return 0;
    17. }
    У кого что?
     
  9. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    Ну это внутрення кухня (откуда цитата?).
    А по приоритетам вроде, сначало должно выполниться действия с UCHARоми, а потом приобразоваваться.
    Иначе неразбириха получается - кагда вздумается делаем в 4 байта, а где в байт
    Например: int - (uchar - uchar)*char + ushort
    тут даже умножение получается неопределенным если есть переполнение в байте.
     
  10. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    У меня int
    хотя если любой из p преоброзовать в UINT
    то и будет unsigned int
    Хотя странно unsigned char к инту хирачить
     
  11. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    SWR
    draft Стандарта-2009
     
  12. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    2009 - это шутка??
    Или сначало написали как удобно, а потом стандарт подгоняют.
     
  13. domov0i

    domov0i New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    74
    Предлагаю перенести эту строчку в раздел wasm.heap в "улыбнитесь"...

    порадовало мою больную психику...

    извиняюсь за флуд...
     
  14. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    А че тут смешного??
    Когда компилятор действия над безнаковыми числами приводит к знаковому.
     
  15. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Получается компилятор выражение в int считает, а чего... :/
    Странно как-то.
    Вот так:
    UCHAR p1 = 7;
    UCHAR p2 = 8;
    UINT p = (UCHAR)(p1 - p2);
    Результат: p=255

    А вот так:
    UCHAR p1 = 7;
    UCHAR p2 = 8;
    UINT p = (UCHAR)p1 - (UCHAR)p2;
    Результат: p=0FFFFFFFFh

    Чё-та я логики вообще не вижу, чего он к int преобразует.
     
  16. SWR

    SWR New Member

    Публикаций:
    0
    Регистрация:
    11 май 2006
    Сообщения:
    226
    Адрес:
    Russia
    Ну это понятно когда явное преобразования.

    UINT p = (UINT)(p1 - p2);
    Результат: p=255
    Да, тут он сначало вычисляет в байтах, а потом приводит к UINT

    UINT p = p1 - p2;
    Результат: p=UINT(-1)
    почему так, по идее должно быть как выше тоже 255.

    >>Чё-та я логики вообще не вижу, чего он к int преобразует.
    Выше _DEN_ довал код печатуещий тип, так если ему передать f(p1 - p2);
    он выведет int (я бы еще понял если было UINT)

    Вот я и спрашиваю какая тут логика
    Например как нужно вычислять
    int - (uchar - uchar)*char + ushort
     
  17. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3. 00411390  push        ebp  
    4. 00411391  mov         ebp,esp
    5. 00411393  sub         esp,0E4h
    6. 00411399  push        ebx  
    7. 0041139A  push        esi  
    8. 0041139B  push        edi  
    9. 0041139C  lea         edi,[ebp-0E4h]
    10. 004113A2  mov         ecx,39h
    11. 004113A7  mov         eax,0CCCCCCCCh
    12. 004113AC  rep stos    dword ptr es:[edi]
    13.     unsigned char p1=7;
    14. 004113AE  mov         byte ptr [p1],7
    15.   unsigned char p2=8;
    16. 004113B2  mov         byte ptr [p2],8
    17.   unsigned int res=p1-p2;
    18. 004113B6  movzx       eax,byte ptr [p1]
    19. 004113BA  movzx       ecx,byte ptr [p2]
    20. 004113BE  sub         eax,ecx
    21. 004113C0  mov         dword ptr [res],eax
    22.   std::cout<<res;
    23. 004113C3  mov         esi,esp
    24. 004113C5  mov         eax,dword ptr [res]
    25. 004113C8  push        eax  
    26. 004113C9  mov         ecx,dword ptr [__imp_std::cout (418290h)]
    27. 004113CF  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41828Ch)]
    28. 004113D5  cmp         esi,esp
    29. 004113D7  call        @ILT+315(__RTC_CheckEsp) (411140h)
    30.  
    31.   return 0;
    32. 004113DC  xor         eax,eax
    33. }
    34. 004113DE  pop         edi  
    35. 004113DF  pop         esi  
    36. 004113E0  pop         ebx  
    37. 004113E1  add         esp,0E4h
    38. 004113E7  cmp         ebp,esp
    39. 004113E9  call        @ILT+315(__RTC_CheckEsp) (411140h)
    40. 004113EE  mov         esp,ebp
    41. 004113F0  pop         ebp  
    42. 004113F1  ret
    >> 4294967295
    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3. 00411390  push        ebp  
    4. 00411391  mov         ebp,esp
    5. 00411393  sub         esp,0E4h
    6. 00411399  push        ebx  
    7. 0041139A  push        esi  
    8. 0041139B  push        edi  
    9. 0041139C  lea         edi,[ebp-0E4h]
    10. 004113A2  mov         ecx,39h
    11. 004113A7  mov         eax,0CCCCCCCCh
    12. 004113AC  rep stos    dword ptr es:[edi]
    13.     unsigned char p1=7;
    14. 004113AE  mov         byte ptr [p1],7
    15.   unsigned char p2=8;
    16. 004113B2  mov         byte ptr [p2],8
    17.   unsigned int res=(unsigned char)p1-(unsigned char)p2;
    18. 004113B6  movzx       eax,byte ptr [p1]
    19. 004113BA  movzx       ecx,byte ptr [p2]
    20. 004113BE  sub         eax,ecx
    21. 004113C0  mov         dword ptr [res],eax
    22.   std::cout<<res;
    23. 004113C3  mov         esi,esp
    24. 004113C5  mov         eax,dword ptr [res]
    25. 004113C8  push        eax  
    26. 004113C9  mov         ecx,dword ptr [__imp_std::cout (418290h)]
    27. 004113CF  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41828Ch)]
    28. 004113D5  cmp         esi,esp
    29. 004113D7  call        @ILT+315(__RTC_CheckEsp) (411140h)
    30.  
    31.   return 0;
    32. 004113DC  xor         eax,eax
    33. }
    34. 004113DE  pop         edi  
    35. 004113DF  pop         esi  
    36. 004113E0  pop         ebx  
    37. 004113E1  add         esp,0E4h
    38. 004113E7  cmp         ebp,esp
    39. 004113E9  call        @ILT+315(__RTC_CheckEsp) (411140h)
    40. 004113EE  mov         esp,ebp
    41. 004113F0  pop         ebp  
    42. 004113F1  ret
    >> 4294967295
    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3. 00411390  push        ebp  
    4. 00411391  mov         ebp,esp
    5. 00411393  sub         esp,0E4h
    6. 00411399  push        ebx  
    7. 0041139A  push        esi  
    8. 0041139B  push        edi  
    9. 0041139C  lea         edi,[ebp-0E4h]
    10. 004113A2  mov         ecx,39h
    11. 004113A7  mov         eax,0CCCCCCCCh
    12. 004113AC  rep stos    dword ptr es:[edi]
    13.     unsigned char p1=7;
    14. 004113AE  mov         byte ptr [p1],7
    15.   unsigned char p2=8;
    16. 004113B2  mov         byte ptr [p2],8
    17.   unsigned int res=(unsigned char)(p1-p2);
    18. 004113B6  movzx       eax,byte ptr [p1]
    19. 004113BA  movzx       ecx,byte ptr [p2]
    20. 004113BE  sub         eax,ecx
    21. 004113C0  movzx       edx,al
    22. 004113C3  mov         dword ptr [res],edx
    23.   std::cout<<res;
    24. 004113C6  mov         esi,esp
    25. 004113C8  mov         eax,dword ptr [res]
    26. 004113CB  push        eax  
    27. 004113CC  mov         ecx,dword ptr [__imp_std::cout (418290h)]
    28. 004113D2  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41828Ch)]
    29. 004113D8  cmp         esi,esp
    30. 004113DA  call        @ILT+315(__RTC_CheckEsp) (411140h)
    31.  
    32.   return 0;
    33. 004113DF  xor         eax,eax
    34. }
    35. 004113E1  pop         edi  
    36. 004113E2  pop         esi  
    37. 004113E3  pop         ebx  
    38. 004113E4  add         esp,0E4h
    39. 004113EA  cmp         ebp,esp
    40. 004113EC  call        @ILT+315(__RTC_CheckEsp) (411140h)
    41. 004113F1  mov         esp,ebp
    42. 004113F3  pop         ebp  
    43. 004113F4  ret
    >> 255

    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3. 00411390  push        ebp  
    4. 00411391  mov         ebp,esp
    5. 00411393  sub         esp,0D8h
    6. 00411399  push        ebx  
    7. 0041139A  push        esi  
    8. 0041139B  push        edi  
    9. 0041139C  lea         edi,[ebp-0D8h]
    10. 004113A2  mov         ecx,36h
    11. 004113A7  mov         eax,0CCCCCCCCh
    12. 004113AC  rep stos    dword ptr es:[edi]
    13.     unsigned char p1=7;
    14. 004113AE  mov         byte ptr [p1],7
    15.   unsigned char p2=8;
    16. 004113B2  mov         byte ptr [p2],8
    17.   std::cout<<p1-p2;
    18. 004113B6  movzx       eax,byte ptr [p1]
    19. 004113BA  movzx       ecx,byte ptr [p2]
    20. 004113BE  sub         eax,ecx
    21. 004113C0  mov         esi,esp
    22. 004113C2  push        eax  
    23. 004113C3  mov         ecx,dword ptr [__imp_std::cout (418290h)]
    24. 004113C9  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (418294h)]
    25. 004113CF  cmp         esi,esp
    26. 004113D1  call        @ILT+315(__RTC_CheckEsp) (411140h)
    27.  
    28.   return 0;
    29. 004113D6  xor         eax,eax
    30. }
    31. 004113D8  pop         edi  
    32. 004113D9  pop         esi  
    33. 004113DA  pop         ebx  
    34. 004113DB  add         esp,0D8h
    35. 004113E1  cmp         ebp,esp
    36. 004113E3  call        @ILT+315(__RTC_CheckEsp) (411140h)
    37. 004113E8  mov         esp,ebp
    38. 004113EA  pop         ebp  
    39. 004113EB  ret
    >> -1


    Студия 2005
     
  18. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    SWR

    Если результирующий тип не вмещает результат выражения, то результат может быть расширен до инта.

    Добавлено: Всмысле "расширяется", а не "может быть расширен".
     
  19. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    В общем спросил в другом месте, получил тот же ответ что давал RedLord

    Т.е. в выражении операнды преобразуются в int если в него влазят, и в unsigned int если нет.
    У нас в выражении влазят - потому int.
    Нифига :) По крайней мере на VS6 0xFFFFFFFF.
    Проверь ещё раз.
     
  20. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    SWR перепутал скорей всего UINT с UCHAR в 2005 >> 0xFFFFFFFF

    В g++ (3.4.4) тоже самое >> 0xFFFFFFFF с UCHAR >> 255
    В gcc (3.4.4) аналогично
    Код (Text):
    1. #include <stdio.h>
    2.  
    3. int main(void)
    4. {
    5.   unsigned char p1=7;
    6.   unsigned char p2=8;
    7.   unsigned int res = (unsigned int)(p1-p2);
    8.   printf ("%u",res);
    9.   return 0;
    10. }
    Код (Text):
    1.         .file   "1.c"
    2.         .section        .rodata
    3. .LC0:
    4.         .string "%u"
    5.         .text
    6.         .p2align 2,,3
    7. .globl main
    8.         .type   main, @function
    9. main:
    10.         pushl   %ebp
    11.         movl    %esp, %ebp
    12.         subl    $8, %esp
    13.         andl    $-16, %esp
    14.         movl    $0, %eax
    15.         addl    $15, %eax
    16.         addl    $15, %eax
    17.         shrl    $4, %eax
    18.         sall    $4, %eax
    19.         subl    %eax, %esp
    20.         movb    $7, -1(%ebp)
    21.         movb    $8, -2(%ebp)
    22.         movzbl  -1(%ebp), %edx
    23.         movzbl  -2(%ebp), %eax
    24.         subl    %eax, %edx
    25.         movl    %edx, %eax
    26.         movl    %eax, -8(%ebp)
    27.         subl    $8, %esp
    28.         pushl   -8(%ebp)
    29.         pushl   $.LC0
    30.         call    printf
    31.         addl    $16, %esp
    32.         movl    $0, %eax
    33.         leave
    34.         ret
    35.         .size   main, .-main
    36.         .ident  "GCC: (GNU) 3.4.4 [FreeBSD] 20050518"