Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2005.09.25;
Скачать: [xml.tar.bz2];

Вниз

Что означает "absolute", и почему он не работает?   Найти похожие ветки 

 
Мир   (2005-08-29 02:37) [0]

var
 DeviceMode : TDevMode absolute 0;

И здесь возникает ошибка. А в чём она?
И что вообще означает абсолютный ноль?


 
KilkennyCat ©   (2005-08-29 02:41) [1]

А что Вы хотели получить?


 
Джо ©   (2005-08-29 02:41) [2]

var
 A: Byte;
 B: Byte absolute A;

Переменная B будет расположена по тому же адресу в памяти, что и A.
Пример посложнее:
var
 A: Word;
 B: Byte absolute A;

Попробуй догадаться, что в этом случае будет содержаться в переменной B.


 
Almaz ©   (2005-08-29 02:45) [3]


> И что вообще означает абсолютный ноль?

Абсолютный ноль - это начало отсчёта абсолютной температуры; расположен на 273,16 К ниже температуры тройной точки воды. Существование абсолютной температуры и А. н. следует из второго начала термодинамики; из третьего начала термодинамики следует, что А. н. недостижим. С приближением температуры к А. н. стремятся к нулю тепловые характеристики вещества: энтропия, теплоёмкость, коэффициент теплового расширения. Резкое снижение интенсивности теплового движения атомов и молекул вблизи А. н. приводит к тому, что все вещества в этих условиях имеют упорядоченную кристаллическую структуру (исключение составляет жидкий гелий).


 
KilkennyCat ©   (2005-08-29 02:48) [4]


> [3] Almaz ©   (29.08.05 02:45)


И в таком случае, DeviceMode - это перечень характеристик сосуда (возможно, Дюара, или Дьюара, но неважно), в котором может быть получено необходимое.


 
Almaz ©   (2005-08-29 02:53) [5]


> И здесь возникает ошибка.

Ошибка возникает потому, что при абсолютном нуле память, где храниться эта переменная, как было сказано выше, приобретает упорядоченную кристаллическую структуру и становиться очень хрупкой. Поэтому любое обращение к ней ведет к ее разрушению - отсюда и Access Violation. ;)


 
Мир   (2005-08-29 02:53) [6]


> Джо ©   (29.08.05 02:41) [2]
> var
>  A: Byte;
>  B: Byte absolute A;
> Переменная B будет расположена по тому же адресу в памяти,
> что и A.
> Пример посложнее:
> var
>  A: Word;
>  B: Byte absolute A;
> Попробуй догадаться, что в этом случае будет содержаться
> в переменной B.


Первый байт переменной А ?
А если 0, то что тогда там оказывается ? Или так писать просто нельзя ?


> Almaz ©   (29.08.05 02:45) [3]
>
> > И что вообще означает абсолютный ноль?
>
> Абсолютный ноль - это начало отсчёта абсолютной температуры;
> расположен на 273,16 К ниже температуры тройной точки воды.

Слабоваты вы в программировании, молодой человек.


 
KilkennyCat ©   (2005-08-29 02:58) [7]


> [5] Almaz ©   (29.08.05 02:53)


Нет, ошибка возникает раньше.
Поскольку для достижения абсолютного нуля требуется некоторое время, возникает момент, когда данный участок памяти получает эффект сверхпроводимости. Отсюда два варианта: данные не могут там зафиксироваться, "скользят" мимо, либо наступает мощная десинхронизация с остальными процессами, так как они начинают сильно тормозить, относительно данного участка памяти.
Поэтому, ошибка возникает раньше, что подтверждает третье начало термодинамики - А. н. недостижим.


 
Германн ©   (2005-08-29 02:58) [8]

2 Almaz ©
Хорошо сказано!

2 Мир   (29.08.05 02:37
Есть директива absolute, которая означает, что переменная слева от оной расположена (должна быь) в памяти по тому же адресу, что и переменная справа от оной. Причем вместо переменной справа может быть указан реальный адрес в памяти! Но вот в какой памяти? Тут есть вопрос.


 
Джо ©   (2005-08-29 02:59) [9]


>  [6] Мир   (29.08.05 02:53)
> Первый байт переменной А ?

Да.
---
Вот так писать можно было в TurboPascal"е

var
 Variable: Byte absolute 0:0; {сегмент:смещение}

Надеюсь, не стоит объяснять, почему это было бы бессмысленно в приложении для Windows?
А остальное, все что вы хотели знать об absolute, но боялись спросить, находится в Справке. Достаточно подвести курсор к слову absolute и нажать F1.


 
Defunct ©   (2005-08-29 03:04) [10]

Мир   (29.08.05 2:53) [6]
> А если 0, то что тогда там оказывается ? Или так
писать просто нельзя ?


Туда в защищенном режиме вас система не пускает. Хотите обращаться по абсолютному адресу 0 - работайте в реальном режиме процессора или переведите проц в виртуальный режим. Тогда при обращении по адресу 0 упретесь в вектор "Devide by zero".


 
Defunct ©   (2005-08-29 03:06) [11]

> "Devide by zero".

zzzz конечно же
"divide by zero"


 
Джо ©   (2005-08-29 03:06) [12]

[8] Германн ©   (29.08.05 02:58)
>  Причем вместо переменной справа может быть указан реальный
> адрес в памяти!

Хотелось бы увидеть пример. ;>
Кстати, Справка, кажется немного привирает на сей счет. И пример разрешения ошибки Variable Name Expected выглядит достаточно безумно. Текст небольшой, поэтому для удобства приведу весь:

This error message is issued if you try to declare an absolute variable, but the absolute directive is not followed by an integer constant or a variable name.

program Produce;

var
 I : Integer;
 J : Integer absolute Addr(I);   (*<-- Error message here*)

begin
end.
program Solve;

const
 Addr = 0; // к чему это вообще?

var
 I : Integer;
 J : Integer absolute I;

begin
end.


 
Юрий Зотов ©   (2005-08-29 03:08) [13]

Дополнение к [3].

Примеры приближения к абсолютному нулю можно найти здесь:
http://www.delphimaster.ru/nuts/nuts.html

> Мир (29.08.05 02:37)

А если серьезно, то директива absolute в объявлении переменной задает адрес, по которому компилятор должен разместить эту переменную. Как и в других случаях прямого управления памятью, вся ответственность за последствия здесь ложится на программиста, поэтому пользоваться этим способом надо аккуратно, полностью понимая, что и зачем ты делаешь - а если полного понимания нет, то использовать его не стоит. Скажем, в Вашем примере делается попытка разместить переменную в запрещенной для прикладного кода области памяти, поэтому и возникает ошибка. И это еще лучший результат, а бывает и гораздо хуже, когда формальной ошибки нет и сообщения не возникает, но есть логическая ошибка и содержимое какой-то области памяти просто портится, без всяких сообщений. Такие ошибки обычно проявляются где-то совершенно в другом месте кода и искать их причину бывает очень непросто.


 
Джо ©   (2005-08-29 03:11) [14]


> [8] Германн ©   (29.08.05 02:58)
>  [13] Юрий Зотов ©   (29.08.05 03:08)

Ребята, вы что - издеваетесь? Да это просто не скомпилируется!
Прошу все же обратить внимание на [12]


 
Юрий Зотов ©   (2005-08-29 03:14) [15]

> Джо ©   (29.08.05 03:11) [14]

Непринципиально. Не в ентом суть.


 
Джо ©   (2005-08-29 03:16) [16]


>  [15] Юрий Зотов ©   (29.08.05 03:14)
> Непринципиально. Не в ентом суть.

Пардон, синтаксис языка, это, все-таки, по моему мнению, вещь принципиальная.


 
Германн ©   (2005-08-29 03:18) [17]

2 Джо ©   (29.08.05 03:06) [12]
>[8] Германн ©   (29.08.05 02:58)
>>  Причем вместо переменной справа может быть указан реальный
>> адрес в памяти!

>Хотелось бы увидеть пример. ;>

Могу привести реальный пример, но для ДОС! Если он тебе нужен, сообщи.
А вообще, Юрий Зотов ©   (29.08.05 03:08) [13] сказал всё, что бы понять смысл этой директивы. Имхо.


 
Джо ©   (2005-08-29 03:21) [18]

[17] Германн ©   (29.08.05 03:18)
> Могу привести реальный пример, но для ДОС!

Реальный пример для Турбо Паскаля я уже привел. Это была фича его синтаксиса. Активно, кстати, использовавшаяся. И мною, в том числе.

> А вообще, Юрий Зотов ©   (29.08.05 03:08) [13] сказал всё,
> что бы понять смысл этой директивы.

Я же считаю, что в данном случае Юрий допустил принципиальную ошибку, сказав:

> . Скажем, в Вашем примере делается попытка разместить переменную
> в запрещенной для прикладного кода области памяти, поэтому
> и возникает ошибка.

Потому что, ошибку вызывает совсем не это. Ошибка - синтаксическая, не имеющая никакого отношения к доступу к "запрещенной для прикладного кода области памяти".


 
Defunct ©   (2005-08-29 03:22) [19]

> Addr = 0; // к чему это вообще?

Вероятно к тому, чтобы показать что препроцессор не знает слова Addr? Addr это ж функция модуля system.

function Addr(X): Pointer;


 
Германн ©   (2005-08-29 03:25) [20]

2 Джо ©   (29.08.05 03:06) [12]

Имхо, принцип компиллятора ТР и Дэльфи - сначала декларируется, потом используется!

А у тебя - наоборот!
Сначала ты используешь - "J : Integer absolute Addr(I);",
А потом декларируешь - "const
Addr = 0;"


 
Джо ©   (2005-08-29 03:27) [21]


> [20] Германн ©   (29.08.05 03:25)

Прости, но ты невнимательно прочитал приведенный мной текст из Справки.


 
Юрий Зотов ©   (2005-08-29 03:29) [22]

> Джо ©   (29.08.05 03:16) [16]

Ну, отлавливает компилятор такие явные ошибки, ну и что? А если бы не отлавливал? Или если ошибка не настолько явная, что он способен ее отловить - тогда как?

Не в синтаксисе кода тут суть, а в его смысле.


 
Германн ©   (2005-08-29 03:41) [23]

Проснулась жена. Требует чтобы я тоже пошел спать.
Пытался найти оправдания, не получилось. :(
Так что пока. До завтра.


 
Джо ©   (2005-08-29 03:45) [24]


> [22] Юрий Зотов ©   (29.08.05 03:29)

ИМХО, если бы дело обстояло так, тогда следовало бы предупреждение об ошибке назвать как-то так "improper memory reference" или "direct memory access not allowed" и тп. Но никак не "Variable name required".


 
Юрий Зотов ©   (2005-08-29 03:56) [25]

> Джо ©   (29.08.05 03:45) [24]

Да какая разница, как ее назвать-то? Ну да, изменили они синтаксис absolute, бывшая run-time ошибка попала в разряд синтаксических, так и что с того? Суть-то не изменилась. И в ДОСе, напрямую задав ошибочный адрес, можно было напортачить ой как запросто.

Кстати, уже не помню - Турбо Паскаль пропускал прямую адресацию в область векторов прерываний (первые 256 байт?)


 
Джо ©   (2005-08-29 03:59) [26]

[25] Юрий Зотов ©   (29.08.05 03:56)
> Кстати, уже не помню - Турбо Паскаль пропускал прямую адресацию
> в область векторов прерываний

Угу, куда угодно. Преспокойным образом. Только синтаксис, разумеется был с указанием сегмент:смещение. Удобная была вещь. Удобно также было размещать массив байтов по адресу $B800:0000. :)


 
Джо ©   (2005-08-29 04:00) [27]


>  [26] Джо ©   (29.08.05 03:59)

Почему удобная? Потому что во многих случаях помогала избегать ассемблерных вставок.


 
GuAV ©   (2005-08-29 04:02) [28]


> Турбо Паскаль пропускал прямую адресацию в область
> векторов прерываний


BP70 точно пропускал.

> (первые 256 байт?)
256 * SizeOf(Pointer) = 1KБ


 
Джо ©   (2005-08-29 04:02) [29]

[26] Джо ©   (29.08.05 03:59)
> так и что с того?

Да ничего, разумеется ;) Просто я посчитал, раз новичку толкуют о синтаксической конструкции, то точность не помешает ;)


 
Мир   (2005-08-29 04:09) [30]

А может кто нибудь привести пример, когда бы абсолют был бы реально нужен ?


 
Джо ©   (2005-08-29 04:18) [31]


>  [30] Мир   (29.08.05 04:09)

Задай поиск по всем файлам в папке /source с вхождением слова "absolute". Там увидишь немало примеров практического применения. Но я, честно говоря, не знаю не одной задачи, которую нельзя было бы решить, не используя absolute.


 
Джо ©   (2005-08-29 04:20) [32]


> [31] Джо ©   (29.08.05 04:18)

Сам последовал своему совету. И убедился, что absolute использует редко. Что и подтверждает, что без него запросто можно обойтись, а его необоснованное использование - дурной тон.


 
Юрий Зотов ©   (2005-08-29 04:40) [33]

> Мир   (29.08.05 04:09) [30]

var
 I: integer;
 U: cardinal absolute I;
 P: pointer absolute I;
 F: single absolute I;
 A: packed array[0..3] of byte absolute I;
 W: packed array[0..1] of word absolute I;
 C: packed array[0..3] of char absolute I;
 S: string[3] absolute I;
 O: TObject absolute I;

Все эти переменные расположены в одной и той же области памяти длиной 4 байта. Обращаясь к ней по имени I, мы трактуем ее содержимое, как знаковое целое; по имени U - как беззнаковое целое; по имени P - как указатель; по имени F - как число с плавающей точкой; по имени A - как массив из 4-х байт, по имени W - как массив из 2-х слов; по имени C - как массив из 4-х символов; по имени S - как короткую строку; по имени O - как ссылку на экземпляр объекта (причем в случае массивов можем работать с их элементами напрямую). Иногда такие фокусы бывают полезны, но злоупотреблять ими не стоит, потому что они все же запутывают код. Тот же результат дает прямое приведение типа, но оно более читабельно, например:

var
 F: single;
begin
 Caption := IntToStr(Integer(F));


 
Юрий Зотов ©   (2005-08-29 05:16) [34]

> Мир   (29.08.05 04:09) [30]

Вот более реальный пример. Предположим, есть понятие "код студента". Он занимает 4 байта и состоит из 4-х однобайтовых полей: код института, код факультета, код группы и личный код. Вся эта структура описывается такой записью:

type
 TStudent = packed record
   Institute: byte;
   Faculty: byte;
   Group: byte;
   Person: byte
 end;

Есть переменная S типа TStudent и ее необходимо записать в INI-файл. Для этого удобно использовать объект TIniFile, но он не имеет методов для записи и чтения сложных структур - то есть, напрямую переменную S в него не запишешь. Зато он имеет методы для записи и чтения целых 4-байтовых чисел, поэтому мы можем сделать так:

var
 I: integer absolute S;
...
 IniFile.WriteInteger(секция, ФИО, I); // Неявная запись S.
...
 I := IniFile.ReadInteger(секция, ФИО, 0); // Неявное чтение S.


 
Мир   (2005-08-29 06:35) [35]

Спасибо.


 
Anatoly Podgoretsky ©   (2005-08-29 08:52) [36]

Мир   (29.08.05 02:37)  
-273°С


 
TUser ©   (2005-08-29 08:53) [37]

> на 273,16 К ниже температуры тройной точки воды

Ниже температуры замерзания воды при 101,3кПа. В тройной точке температура на 0,0076 градуса выше.


 
Думкин ©   (2005-08-29 08:55) [38]

> Anatoly Podgoretsky ©   (29.08.05 08:52) [36]

Есть неточность. И всегда будет. Точно:
0°К

А про абсолютный ноль и его достижимость - из 2-х первых - не так. На самом деле - это 3-е начало. Всего лишь.


 
Anatoly Podgoretsky ©   (2005-08-29 09:06) [39]

Юрий Зотов ©   (29.08.05 05:16) [34]
Что реализуется также с помощью вариантных записей или что еще лучше приведения. Ценность absolute была высока в программах реального режима, для указания абсолютных аппаратных ресурсов, но часто использовалась не совсем по делу. И перенос этой технологии на Дельфи не обоснован, если не сказать прямо, как правило приносящий больше вреда, чем реальной пользы.


 
yuryzh ©   (2005-08-29 15:49) [40]

Этот пример взят из реального кода.
var
  DeviceMode : TDevMode absolute 0;
ChangeDisplaySettings(DeviceMode, 0)

Просто в оригинале эта функция описана как
LONG ChangeDisplaySettings(
 LPDEVMODE lpDevMode,  // graphics mode
 DWORD dwflags         // graphics mode options
);

а в Delphi
function ChangeDisplaySettings(
 var lpDevMode: TDeviceMode;
 dwFlags: DWORD): Longint; stdcall;

и для передачи var параметра, адрес которого есть nil использовалась конструкция
DeviceMode : TDevMode absolute 0;



Страницы: 1 2 вся ветка

Форум: "Потрепаться";
Текущий архив: 2005.09.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.04 c
14-1125639886
palva
2005-09-02 09:44
2005.09.25
Вы пьете вино из картонных коробок?


3-1123259807
Оран Гутангович
2005-08-05 20:36
2005.09.25
could not convert variant of type(Null) into type (String)


1-1125898664
leonidus
2005-09-05 09:37
2005.09.25
Как обновить TEdit


4-1122704571
Gloomer
2005-07-30 10:22
2005.09.25
Перехват перехода в спящий/ждущий режим


1-1125559683
Суслик
2005-09-01 11:28
2005.09.25
Свой менеджер памяти





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский