Вот код: UCHAR p1 = 7; UCHAR p2 = 8; UINT p = p1 - p2; После выполнения в p UINT(-1). Но p1 - p2 должно быть равно 255, и приравнивание к UINT недолжно приводить к расширению знака. Вопрос: Это так задумано или опять выпендреж мелкомагких.
НУ float p1 = 9.1; float p2 = 8.5; UINT p = p1 - p2; тут p равно 0 если как ты предлагаеш UINT p = p1 - p2 == (UINT)p1 - (UINT)p2 то должно 1
Ну как и ожидалось, 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)
ИМХО: пункт 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.
Код (Text): #include <iostream> template <class T> void f(T) { std::cout << typeid(T).name() << std::endl; } int main() { unsigned char p1 = 7; unsigned char p2 = 8; f(p1 - p2); return 0; } У кого что?
Ну это внутрення кухня (откуда цитата?). А по приоритетам вроде, сначало должно выполниться действия с UCHARоми, а потом приобразоваваться. Иначе неразбириха получается - кагда вздумается делаем в 4 байта, а где в байт Например: int - (uchar - uchar)*char + ushort тут даже умножение получается неопределенным если есть переполнение в байте.
У меня int хотя если любой из p преоброзовать в UINT то и будет unsigned int Хотя странно unsigned char к инту хирачить
Предлагаю перенести эту строчку в раздел wasm.heap в "улыбнитесь"... порадовало мою больную психику... извиняюсь за флуд...
Получается компилятор выражение в 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 преобразует.
Ну это понятно когда явное преобразования. 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
Код (Text): int _tmain(int argc, _TCHAR* argv[]) { 00411390 push ebp 00411391 mov ebp,esp 00411393 sub esp,0E4h 00411399 push ebx 0041139A push esi 0041139B push edi 0041139C lea edi,[ebp-0E4h] 004113A2 mov ecx,39h 004113A7 mov eax,0CCCCCCCCh 004113AC rep stos dword ptr es:[edi] unsigned char p1=7; 004113AE mov byte ptr [p1],7 unsigned char p2=8; 004113B2 mov byte ptr [p2],8 unsigned int res=p1-p2; 004113B6 movzx eax,byte ptr [p1] 004113BA movzx ecx,byte ptr [p2] 004113BE sub eax,ecx 004113C0 mov dword ptr [res],eax std::cout<<res; 004113C3 mov esi,esp 004113C5 mov eax,dword ptr [res] 004113C8 push eax 004113C9 mov ecx,dword ptr [__imp_std::cout (418290h)] 004113CF call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41828Ch)] 004113D5 cmp esi,esp 004113D7 call @ILT+315(__RTC_CheckEsp) (411140h) return 0; 004113DC xor eax,eax } 004113DE pop edi 004113DF pop esi 004113E0 pop ebx 004113E1 add esp,0E4h 004113E7 cmp ebp,esp 004113E9 call @ILT+315(__RTC_CheckEsp) (411140h) 004113EE mov esp,ebp 004113F0 pop ebp 004113F1 ret >> 4294967295 Код (Text): int _tmain(int argc, _TCHAR* argv[]) { 00411390 push ebp 00411391 mov ebp,esp 00411393 sub esp,0E4h 00411399 push ebx 0041139A push esi 0041139B push edi 0041139C lea edi,[ebp-0E4h] 004113A2 mov ecx,39h 004113A7 mov eax,0CCCCCCCCh 004113AC rep stos dword ptr es:[edi] unsigned char p1=7; 004113AE mov byte ptr [p1],7 unsigned char p2=8; 004113B2 mov byte ptr [p2],8 unsigned int res=(unsigned char)p1-(unsigned char)p2; 004113B6 movzx eax,byte ptr [p1] 004113BA movzx ecx,byte ptr [p2] 004113BE sub eax,ecx 004113C0 mov dword ptr [res],eax std::cout<<res; 004113C3 mov esi,esp 004113C5 mov eax,dword ptr [res] 004113C8 push eax 004113C9 mov ecx,dword ptr [__imp_std::cout (418290h)] 004113CF call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41828Ch)] 004113D5 cmp esi,esp 004113D7 call @ILT+315(__RTC_CheckEsp) (411140h) return 0; 004113DC xor eax,eax } 004113DE pop edi 004113DF pop esi 004113E0 pop ebx 004113E1 add esp,0E4h 004113E7 cmp ebp,esp 004113E9 call @ILT+315(__RTC_CheckEsp) (411140h) 004113EE mov esp,ebp 004113F0 pop ebp 004113F1 ret >> 4294967295 Код (Text): int _tmain(int argc, _TCHAR* argv[]) { 00411390 push ebp 00411391 mov ebp,esp 00411393 sub esp,0E4h 00411399 push ebx 0041139A push esi 0041139B push edi 0041139C lea edi,[ebp-0E4h] 004113A2 mov ecx,39h 004113A7 mov eax,0CCCCCCCCh 004113AC rep stos dword ptr es:[edi] unsigned char p1=7; 004113AE mov byte ptr [p1],7 unsigned char p2=8; 004113B2 mov byte ptr [p2],8 unsigned int res=(unsigned char)(p1-p2); 004113B6 movzx eax,byte ptr [p1] 004113BA movzx ecx,byte ptr [p2] 004113BE sub eax,ecx 004113C0 movzx edx,al 004113C3 mov dword ptr [res],edx std::cout<<res; 004113C6 mov esi,esp 004113C8 mov eax,dword ptr [res] 004113CB push eax 004113CC mov ecx,dword ptr [__imp_std::cout (418290h)] 004113D2 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41828Ch)] 004113D8 cmp esi,esp 004113DA call @ILT+315(__RTC_CheckEsp) (411140h) return 0; 004113DF xor eax,eax } 004113E1 pop edi 004113E2 pop esi 004113E3 pop ebx 004113E4 add esp,0E4h 004113EA cmp ebp,esp 004113EC call @ILT+315(__RTC_CheckEsp) (411140h) 004113F1 mov esp,ebp 004113F3 pop ebp 004113F4 ret >> 255 Код (Text): int _tmain(int argc, _TCHAR* argv[]) { 00411390 push ebp 00411391 mov ebp,esp 00411393 sub esp,0D8h 00411399 push ebx 0041139A push esi 0041139B push edi 0041139C lea edi,[ebp-0D8h] 004113A2 mov ecx,36h 004113A7 mov eax,0CCCCCCCCh 004113AC rep stos dword ptr es:[edi] unsigned char p1=7; 004113AE mov byte ptr [p1],7 unsigned char p2=8; 004113B2 mov byte ptr [p2],8 std::cout<<p1-p2; 004113B6 movzx eax,byte ptr [p1] 004113BA movzx ecx,byte ptr [p2] 004113BE sub eax,ecx 004113C0 mov esi,esp 004113C2 push eax 004113C3 mov ecx,dword ptr [__imp_std::cout (418290h)] 004113C9 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (418294h)] 004113CF cmp esi,esp 004113D1 call @ILT+315(__RTC_CheckEsp) (411140h) return 0; 004113D6 xor eax,eax } 004113D8 pop edi 004113D9 pop esi 004113DA pop ebx 004113DB add esp,0D8h 004113E1 cmp ebp,esp 004113E3 call @ILT+315(__RTC_CheckEsp) (411140h) 004113E8 mov esp,ebp 004113EA pop ebp 004113EB ret >> -1 Студия 2005
SWR Если результирующий тип не вмещает результат выражения, то результат может быть расширен до инта. Добавлено: Всмысле "расширяется", а не "может быть расширен".
В общем спросил в другом месте, получил тот же ответ что давал RedLord Т.е. в выражении операнды преобразуются в int если в него влазят, и в unsigned int если нет. У нас в выражении влазят - потому int. Нифига По крайней мере на VS6 0xFFFFFFFF. Проверь ещё раз.
SWR перепутал скорей всего UINT с UCHAR в 2005 >> 0xFFFFFFFF В g++ (3.4.4) тоже самое >> 0xFFFFFFFF с UCHAR >> 255 В gcc (3.4.4) аналогично Код (Text): #include <stdio.h> int main(void) { unsigned char p1=7; unsigned char p2=8; unsigned int res = (unsigned int)(p1-p2); printf ("%u",res); return 0; } Код (Text): .file "1.c" .section .rodata .LC0: .string "%u" .text .p2align 2,,3 .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp movb $7, -1(%ebp) movb $8, -2(%ebp) movzbl -1(%ebp), %edx movzbl -2(%ebp), %eax subl %eax, %edx movl %edx, %eax movl %eax, -8(%ebp) subl $8, %esp pushl -8(%ebp) pushl $.LC0 call printf addl $16, %esp movl $0, %eax leave ret .size main, .-main .ident "GCC: (GNU) 3.4.4 [FreeBSD] 20050518"