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





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Всё понятно, спасибо... Глаза мои раскрылись ;-) 04.12.03 15:48  Число просмотров: 1300
Автор: 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-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach