информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Сетевые кракеры и правда о деле ЛевинаСтрашный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
Всё понятно, спасибо... Глаза мои раскрылись ;-) 04.12.03 15:48  Число просмотров: 1390
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
<programming>
[C++] Нифига не понимаю... Help, please... 04.12.03 14:46  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 04.12.03 14:49  Количество правок: 1
<"чистая" ссылка>
Итак, имеем функцию на этом бесконечно мудром языке:
(взято из примера по low-level NTFS programming)
VOID ReadExternalAttribute(
  PNONRESIDENT_ATTRIBUTE attr,
  ULONGLONG vcn, ULONG count, PVOID buffer)
{
  ULONGLONG lcn, runcount;
  ULONG readcount, left;
  PUCHAR bytes = PUCHAR(buffer);

  for (left = count; left > 0; left -= readcount) {
    FindRun(attr, vcn, &lcn, &runcount);

    readcount = ULONG(min(runcount, left));

    ULONG n = readcount * bootb.BytesPerSector * bootb.SectorsPerCluster;

    if (lcn == 0)
      memset(bytes, 0, n);
    else
      ReadLCN(lcn, readcount, bytes);

    vcn += readcount; //Вот здесь непонятки ;-)
    bytes += n;
  }
}

---

Почему в параметр vcn, переданный в функцию в стеке, делают присвоение с инкрементом? Насколько я понимаю, это делать нельзя (вернее, бессмысленно ;-).

Заранее всем спасибо.
[C++] Почему буссмысленно? 04.12.03 14:58  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка>
> Итак, имеем функцию на этом бесконечно мудром языке:
> (взято из примера по low-level NTFS programming)
>
> VOID ReadExternalAttribute(
>   PNONRESIDENT_ATTRIBUTE attr,
>   ULONGLONG vcn, ULONG count, PVOID buffer)
> {
>   ULONGLONG lcn, runcount;
>   ULONG readcount, left;
>   PUCHAR bytes = PUCHAR(buffer);
> 
>   for (left = count; left > 0; left -= readcount) {
>     FindRun(attr, vcn, &lcn, &runcount);
> 
>     readcount = ULONG(min(runcount, left));
> 
>     ULONG n = readcount * bootb.BytesPerSector *
> bootb.SectorsPerCluster;
> 
>     if (lcn == 0)
>       memset(bytes, 0, n);
>     else
>       ReadLCN(lcn, readcount, bytes);
> 
>     vcn += readcount; //Вот здесь непонятки ;-)
>     bytes += n;
>   }
> }
> 

---

> Почему в параметр vcn, переданный в функцию в стеке, делают
> присвоение с инкрементом? Насколько я понимаю, это делать
> нельзя (вернее, бессмысленно ;-).

Переменная vcn глобальна для всей процедуры и поэтому доступна до выхода из процедуры. А в данном случае она увеличивается на кол-во байтов, считанных из LCN'а и подготавливается для следующей итерации цикла.

> Заранее всем спасибо.
[C++] Потому что мне на Delphi это переделать надо ;-) Значит ли это, что мне в своей процедуре надо заводить локальную копию vcn? 04.12.03 15:20  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
Т.е. эквивалентно ли это вот такой конструкции:
//Оригинальная процедура:
VOID ReadExternalAttribute(
  PNONRESIDENT_ATTRIBUTE attr,
  ULONGLONG vcn, ULONG count, PVOID buffer)
{
  ULONGLONG lcn, runcount;
  ULONG readcount, left;
  PUCHAR bytes = PUCHAR(buffer);

  for (left = count; left > 0; left -= readcount) {
    FindRun(attr, vcn, &lcn, &runcount);

    readcount = ULONG(min(runcount, left));

    ULONG n = readcount * bootb.BytesPerSector * bootb.SectorsPerCluster;

    if (lcn == 0)
      memset(bytes, 0, n);
    else
      ReadLCN(lcn, readcount, bytes);

    vcn += readcount; //Вот здесь непонятки ;-)
    bytes += n;
  }
}

//Эквивалент:
  Procedure ReadExternalAttribute(
    attr: PNONRESIDENT_ATTRIBUTE;
    Const vcn: ULONGLONG; count: ULONG; buffer: Pointer);
  Var
    lcn, runcount: ULONGLONG;
    readcount, left, n: ULONG;
    bytes: PUCHAR;
    _vcn: ULONGLONG;
  Begin
    bytes  := buffer;
    left := count;
    _vcn := vcn;
    While left > 0 Do
    Begin
      FindRun(attr, vcn, @lcn, @runcount);
      readcount := min(runcount, left);
      n := readcount * bootb.BytesPerSector * bootb.SectorsPerCluster;
      if lcn = 0 Then ZeroMemory(bytes, n)
      else ReadLCN(lcn, readcount, bytes);
      Inc(_vcn, readcount);
      Inc(bytes, n);
      Dec(left, readcount);
    End;
  End;

---
[C++] А зачем ты ее в заголовке процедуры как Const описываешь? Убери Const и ничего заводить не придется 04.12.03 15:24  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка>
[Pascal] А потому что если я поставлю Var или передам в функцию указатель, то переменная будет изменена _вне_ процедуры. Это подразумевалось в оригинале? 04.12.03 15:30  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
[Pascal] если не ставить ничего лишнего, будет как раз локальная копия переменной, как в варианте на Си 04.12.03 15:34  
Автор: LLL <Алексей> Статус: Member
<"чистая" ссылка>
[Pascal] Да я знаю, специально разжевал, поскольку те, кто шарит в цпп, могут не шарить в delphi, и наоборот, как я ;-) 04.12.03 15:42  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
Конечно, именно так и сделано в оригинале на С 04.12.03 15:32  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
Отредактировано 04.12.03 15:32  Количество правок: 1
<"чистая" ссылка>
А почему тогда это не было сделано явно (в смысле, просто не передали указатель на vcn)? 04.12.03 15:35  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
Sandy что-то перепутал, сказав "конечно", в оригинале именно копия переменной в функции модифицируется, безо всякого влияния на передаваемый аргумент 04.12.03 15:46  
Автор: LLL <Алексей> Статус: Member
<"чистая" ссылка>
Прошу прощения, невольно ввел Хэндла в заблуждение! :) 04.12.03 16:34  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка>
Всё понятно, спасибо... Глаза мои раскрылись ;-) 04.12.03 15:48  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
[C++] Чего же тут непонятного 04.12.03 14:56  
Автор: Cyril <sc> Статус: Member
<"чистая" ссылка>
> Итак, имеем функцию на этом бесконечно мудром языке:
> (взято из примера по low-level NTFS programming)
>
> VOID ReadExternalAttribute(
>   PNONRESIDENT_ATTRIBUTE attr,
>   ULONGLONG vcn, ULONG count, PVOID buffer)
> {
>   ULONGLONG lcn, runcount;
>   ULONG readcount, left;
>   PUCHAR bytes = PUCHAR(buffer);
> 
>   for (left = count; left > 0; left -= readcount) {
>     FindRun(attr, vcn, &lcn, &runcount);
> 
>     readcount = ULONG(min(runcount, left));
> 
>     ULONG n = readcount * bootb.BytesPerSector *
> bootb.SectorsPerCluster;
> 
>     if (lcn == 0)
>       memset(bytes, 0, n);
>     else
>       ReadLCN(lcn, readcount, bytes);
> 
>     vcn += readcount; //Вот здесь непонятки ;-)
>     bytes += n;
>   }
> }
> 

---

> Почему в параметр vcn, переданный в функцию в стеке, делают
> присвоение с инкрементом? Насколько я понимаю, это делать
> нельзя (вернее, бессмысленно ;-).
Почему бессмысленно
ведь FindRun(attr, vcn, &lcn, &runcount); вызывается в цикле с этим параметром
1




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


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