информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Атака на InternetЗа кого нас держат?Spanning Tree Protocol: недокументированное применение
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Блокировка российских аккаунтов... 
 Отзыв сертификатов ЦБ РФ, ПСБ,... 
 Памятка мирным людям во время информационной... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Могу ошибаться, но, вроде бы как в стандарте не стандартизовано неявное приведение типов. Каламбурчик — но суть, думаю ясна. И решение где-то рядом с long long res = l64 / (long long) sizeof(short); 07.03.12 08:18  Число просмотров: 2123
Автор: kstati <Евгений Борисов> Статус: Elderman
<"чистая" ссылка>
<programming>
[C++] на 64bit компайлере вот такая поганка 28.02.12 01:23  
Автор: + <Mikhail> Статус: Elderman
Отредактировано 28.02.12 01:23  Количество правок: 1
<"чистая" ссылка>
кто обяснит сиё , на 64bit компайлере вот такая поганка:
l64 - signed 64bit отрицательное число (например -2) делим на положительное unsigned число к примеру 2
компайлер считает что -2 ето unsigned и делит как unsigned и на выходе фигня = 0x7fffffffffffffff
long long l64 = -2
long long res = l64 / sizeof(short);
?
Могу ошибаться, но, вроде бы как в стандарте не стандартизовано неявное приведение типов. Каламбурчик — но суть, думаю ясна. И решение где-то рядом с long long res = l64 / (long long) sizeof(short); 07.03.12 08:18  
Автор: kstati <Евгений Борисов> Статус: Elderman
<"чистая" ссылка>
sizeof() - size_t - разный размер в зависимости от платформы 07.03.12 18:08  
Автор: :-) <:-)> Статус: Elderman
<"чистая" ссылка>
BTW, а какой компилятор? 02.03.12 14:50  
Автор: AlexD <Alexander> Статус: Member
<"чистая" ссылка>
на 2-х разных пробовал и подозреваю что так на всех 02.03.12 20:31  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка>
это были OpenSource'ные компиляторы? Возможно они друг у друга передрали код ) 02.03.12 21:08  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
майкрософтовский и солярис 02.03.12 23:12  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка>
попробуй прописать директиву для 64-х битной модели,... 03.03.12 04:29  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
попробуй прописать директиву для 64-х битной модели, заменить __int64 на int, скомпилировать и посмотреть что получится.
похоже на ошибку оптимизации с тупым сдвигом регистра. есть возможность отключить оптимизацию вычислений? 29.02.12 01:50  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
оптимизация отключена, debug build, 29.02.12 01:59  
Автор: + <Mikhail> Статус: Elderman
Отредактировано 29.02.12 03:23  Количество правок: 1
<"чистая" ссылка>
оптимизация отключена, debug build,
в ассемблере вызывается

div rax, qword ptr [i]
Почти RTFM 28.02.12 19:53  
Автор: leo <Леонид Юрьев> Статус: Elderman
Отредактировано 28.02.12 19:54  Количество правок: 1
<"чистая" ссылка>
> кто обяснит сиё , на 64bit компайлере вот такая поганка:
> l64 - signed 64bit отрицательное число (например -2) делим
> на положительное unsigned число к примеру 2
> компайлер считает что -2 ето unsigned и делит как unsigned
> и на выходе фигня = 0x7fffffffffffffff
> long long l64 = -2
> long long res = l64 / sizeof(short);
> ?

http://stackoverflow.com/questions/50605/signed-to-unsigned-conversion-in-c-is-it-always-safe
ты внимательней прочти, а потом РТФэкай 29.02.12 01:28  
Автор: + <Mikhail> Статус: Elderman
Отредактировано 29.02.12 01:51  Количество правок: 1
<"чистая" ссылка>
ты внимательней прочти, а потом РТФэкай
а так же скомпилируй 32 а потом 64 и почувствуй разницу.

__int64 f(__int64 i, unsigned __int64 ui) {
  __int64 r = i / ui;
  return r;
}
int main() {
  f(-6, 3);
  return 0;
}

---
может проблема в неявном приобразовании? 29.02.12 13:31  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
может проблема в неявном приобразовании?
попробуй:
__int64 f(__int64 i, unsigned __int64 ui) {
  __int64 r = i / (__int64)ui;
  return r;
}
int main() {
  f(-6, 3);
  return 0;
}

---
почему 32 битный компайлер генерит другой код (правильный)? 01.03.12 07:48  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка>
Что-то не пойму я тебя 29.02.12 12:20  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
> ты внимательней прочти, а потом РТФэкай
> а так же скомпилируй 32 а потом 64 и почувствуй разницу.
>
> __int64 f(__int64 i, unsigned __int64 ui) {
> __int64 r = i / ui;
> return r;
> }
> int main() {
> f(-6, 3);
> return 0;
> }

Компилятор преобразовал -2 в uint64_t (это правильно, см ссылку) получилось 0xFFFF_FFFF_FFFF_FFFE, потом поделил это на 2, результат = 0x7FFF_FFFF_FFFF_FFFF.

Итого = всё правильно.
а ну объясни, почему 32 битный компайлер генерит другой код... 01.03.12 07:47  
Автор: + <Mikhail> Статус: Elderman
Отредактировано 01.03.12 07:51  Количество правок: 2
<"чистая" ссылка>
а ну объясни, почему 32 битный компайлер генерит другой код (правильный)?
32 битный компилятор не преобразовывает -2 в uint64, почему?
[C++] Ну вот, все видно 03.03.12 19:01  
Автор: leo <Леонид Юрьев> Статус: Elderman
Отредактировано 03.03.12 19:01  Количество правок: 1
<"чистая" ссылка>
#include <stdio.h>

void x()
{
    long long l64 = -2;
    long long res = l64 / sizeof(short);

    printf("x) arch=%d.bit, sizeof(long long) = %d, res = %lld = 0x%llX\n", (unsigned)sizeof(void*) * 8, (unsigned)sizeof(long long), res, res);
}

void y()
{
    long long l64 = -2;
    long long res = l64 / ( (unsigned long)sizeof(short) );

    printf("y) arch=%d.bit, sizeof(long long) = %d, res = %lld = 0x%llX\n", (unsigned)sizeof(void*) * 8, (unsigned)sizeof(long long), res, res);
}

void z()
{
    long long l64 = -2;
    long long res = ( (unsigned long long)l64 ) / sizeof(short);

    printf("z) arch=%d.bit, sizeof(long long) = %d, res = %lld = 0x%llX\n", (unsigned)sizeof(void*) * 8, (unsigned)sizeof(long long), res, res);
}

int main(int argc, char** argv)
{
    x();
    y();
    z();
}

---


gcc -m32 x.c && ./a.out
x) arch=32.bit, sizeof(long long) = 8, res = -1 = 0xFFFFFFFFFFFFFFFF
y) arch=32.bit, sizeof(long long) = 8, res = -1 = 0xFFFFFFFFFFFFFFFF
z) arch=32.bit, sizeof(long long) = 8, res = 9223372036854775807 = 0x7FFFFFFFFFFFFFFF


gcc -m64 x.c && ./a.out
x) arch=64.bit, sizeof(long long) = 8, res = 9223372036854775807 = 0x7FFFFFFFFFFFFFFF
y) arch=64.bit, sizeof(long long) = 8, res = 9223372036854775807 = 0x7FFFFFFFFFFFFFFF
z) arch=64.bit, sizeof(long long) = 8, res = 9223372036854775807 = 0x7FFFFFFFFFFFFFFF
Короче, не нужно путать компилятор и он вас путать не будет (IMHO) 03.03.12 19:03  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
ошибка разработчиков компилятора? 01.03.12 11:08  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
проверил на другом компиляторе тоже самое 01.03.12 23:45  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка>
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2022 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach