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





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
sizeof() - size_t - разный размер в зависимости от платформы 07.03.12 18:08  Число просмотров: 2749
Автор: :-) <:-)> Статус: 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-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach