Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: кто глюк - я или студия? ))  (Прочитано 11205 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 23-08-2007 08:29 » 

(в VC++6)

простенький пример
Код:
	BYTE b='а';//русская буква
const BYTE* p=&b;

if(p[0]=='а')
{
int iii=1;//сюда почему то не переходим (?????)
}

а вот так
Цитата
   if(p[0]==(BYTE)'а')

уже правильно переход совершается.
Замечено с русскими буквами, с цифрами и латиницей всё нормально и без (BYTE) работает

так вот - кто глючит , я или студия ?
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 23-08-2007 08:37 » 

разница в коде
Код:
if( p[0]==(BYTE)'з')
0040B135   mov         edx,dword ptr [ebp-8]
0040B138   xor         eax,eax
0040B13A   mov         al,byte ptr [edx]
0040B13C   cmp         eax,0E7h
0040B141   jne         xxxx+0E4h (0040b194)

if( p[0]=='з')
0040B135   mov         edx,dword ptr [ebp-8]
0040B138   xor         eax,eax
0040B13A   mov         al,byte ptr [edx]
0040B13C   cmp         eax,0E7h
0040B13F   jne         xxxx+0E5h (0040b195)

то есть разницы никакой ))) Кроме неправильного перехода
« Последнее редактирование: 23-08-2007 08:39 от Алексей1153++ » Записан

Tuborg
Команда клуба

ee
Offline Offline

« Ответ #2 : 23-08-2007 10:58 » 

А в умолчаниях проекта стоит ANSI или UNICODE?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 23-08-2007 11:37 » 

а фик знает...

опции такие
Код:
/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR"Debug/" /Fp"Debug/FanEngine.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 

где тут что, я не знаю, не разбирадлся никогда )
или где надо поглядеть ?
Записан

Tuborg
Команда клуба

ee
Offline Offline

« Ответ #4 : 23-08-2007 12:28 » 

Я думаю дело всё в этом.... Я всегда там переключаюсь в ANSI. А у тебя как раз получается он по дефолту твою 'a' юникодом читает... а это, как понимаешь, далеко не один байт.

Посмотри Project -> %%ProjectName%% Properties -> Configuration Properties -> Project Defaults -> Character Set -> Use not set (у меня стоит)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 23-08-2007 17:34 » 

у мну в студии нет таких настроек... Либо я не могу найти

самое смешное и непонятное ведь вот в чём: сравнение компилятор делает в обоих случаях одинаково, с нужным числом ('з'==0xE7). А адрес перехода различается. Следовательно, юникод ни при чём, а то бы он сравнивал со словом, а не байтом
« Последнее редактирование: 23-08-2007 17:37 от Алексей1153++ » Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 23-08-2007 21:16 » 

Алексей1153++, Byte это unsigned char. Просто  'a' это signed char в Visual Studio C++6.0 Отсюда вся и пляска с бубном. Я первый раз с этим столкнулся, когда пытался работать с массивом. В качестве индекса выступали символы с текста Улыбаюсь
« Последнее редактирование: 23-08-2007 21:18 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 24-08-2007 03:36 » 

ясно...  буду теперь знать грабли ))
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 24-08-2007 03:40 » 

только всё же непонятный момент - почему ассемблерный код одинаковый, кроме перехода , ведь однин из сравниваемых аргументов - переменная, тогда откуда компилятор выяснил, что равенство не будет выполнено ? Или он сразу по несовпадению типов решил в обход пойти ? Улыбаюсь
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #9 : 24-08-2007 13:24 » 

Лёш,  там скорее всего еше есть код, относяшийся к условию. Теперь о другом. Заметь, у тебя сравнивается с регистром eax. Этот регистр 32 разрядный. Значит Все отрицательные числа, записанные в байт и заполненные в eax изначально будут больще всех положительных чисел.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 24-08-2007 14:23 » 

Finch, ты не прав

//загрузили проверяемый байт в младший байт регистра eax,
//а старшие байты обнулены
0040B138   xor         eax,eax
0040B13A   mov         al,byte ptr [edx]

//сравниваем с числом 0x000000e7 , 3 старшие байта также нулю равны
0040B13C   cmp         eax,0E7h

знак в этом случае ни при чём Улыбаюсь

вижу объяснение такое: компилятор видит, что константа 'з' - "отрицательная". Также он видит, что тип unsigned (заведомо "положительный") сравнивается с отрицательным числом. То есть , по его,компилятора, мнению, результат всегда false
Записан

Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 28-08-2007 06:09 » 

Да, есть такие грабли. Вот простой пример:
Код:
#include <stdio.h>

int main(void)
{
char a = (char)0xe9;
unsigned char b = 0xe9;

if( a == b ) printf("OK\n");
else printf("ERR\n");

return 0;
}
который выводит "ERR".

А вот что сгенерировал компилятор:
Код:
_TEXT	SEGMENT
_a$ = -4
_b$ = -8
_main PROC NEAR ; COMDAT

; 4    : {

push ebp
mov ebp, esp
sub esp, 72 ; 00000048H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-72]
mov ecx, 18 ; 00000012H
mov eax, -858993460 ; ccccccccH
rep stosd

/*
 * Вот здесь показано как компилятор воспринял значение 0xe9
 * для типа "char".
 */
; 5    : char a = (char)0xe9;
mov BYTE PTR _a$[ebp], -23 ; ffffffe9H      /* грабли номер 1 */

/*
 * А здесь для типа "unsigned char".
 */
; 6    : unsigned char b = 0xe9;
mov BYTE PTR _b$[ebp], 233 ; 000000e9H

; 7    :
; 8    : if( a == b ) printf("OK\n");

/*
 * А вот самые главные грабли. Идет загрузка byte с расширением по
 * знаку в "eax" и мы получаем 0xffffffe9.
 */
movsx eax, BYTE PTR _a$[ebp]

/*
 * Здесь все нормально, только странно както. Загружает слово в "ecx",
 * а потом выделяет в нем регистр "cl".
 * Можно было бы и одной командой обойтись: "movzbl -8(%ebp), %ecx"
 */
mov ecx, DWORD PTR _b$[ebp]
and ecx, 255 ; 000000ffH

/*
 * Ну а здесь, результат и так понятен.
 */
cmp eax, ecx
jne SHORT $L341
push OFFSET FLAT:??_C@_03IOOG@OK?6?$AA@ ; `string'
call _printf
add esp, 4

; 9    : else printf("ERR\n");

jmp SHORT $L343
$L341:
push OFFSET FLAT:??_C@_04ILN@ERR?6?$AA@ ; `string'
call _printf
add esp, 4
$L343:

; 10   :
; 11   : return 0;

xor eax, eax

; 12   : }

pop edi
pop esi
pop ebx
add esp, 72 ; 00000048H
cmp ebp, esp
call __chkesp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
« Последнее редактирование: 28-08-2007 06:28 от Serg79 » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 28-08-2007 07:43 » 

Serg79, в твоём асме явно видно, что используется знак, согласен. А в примерах из моего поста - знак не компилчтор явно не применил...
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines