Oberon space
General Category => Общий раздел => Тема начата: valexey_u от Октябрь 30, 2012, 10:02:13 am
-
В сообщении о языке (http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.Report.pdf) про присваивания сказано:
The type of the expression must be the same as that of the designator. The following exceptions hold:
1. The constant NIL can be assigned to variables of any pointer or procedure type.
2. Strings can be assigned to any array of characters, provided the number of characters in the
string is not greater than that of the array. If it is less, a null character (0X) is appended. Singlecharacter strings can also be assigned to variables of type CHAR.
3. In the case of records, the type of the source must be an extension of the type of the destination
Я правильно понимаю, что в результате следующее присваивание не валидно?
VAR
a : LONGREAL;
b : REAL;
BEGIN
a := b;
END;
-
Да, и похоже, что следующее тоже нельзя:
VAR
a : LONGREAL;
BEGIN
a := 42;
END;
-
Первый пример абсолютно невалиден, а вот второй пример -- почему бы и нет? Или литерал 42 обязан быть целого типа?
-
Или литерал 42 обязан быть целого типа?
Да
Numbers are (unsigned) integers or real numbers. Integers are sequences of digits and may be
followed by a suffix letter. If no suffix is specified, the representation is decimal. The suffix H
indicates hexadecimal representation.
A real number always contains a decimal point. Optionally it may also contain a decimal scale
factor. The letter E is pronounced as "times ten to the power of". A real number is of type REAL,
unless it contains a scale factor with the letter D, in which case it is of type LONGREAL.
-
Ну значит надо писать так:
VAR
a : LONGREAL;
BEGIN
a := 42.0D;
END;С другой строны, может так и правильнее -- сразу понятно, что a -- переменная вещественного типа...
Хотя приписывать D неудобно, конечно...
-
Гм. И, похоже, что если четко следовать букве закона из сообщения о языке, то имеем также следующее:
TYPE
A = RECORD END;
B = RECORD (A) END;
PA = POINTER TO A;
PB = POINTER TO B;
VAR
a : A;
b : B;
pa : PA;
pb : PB;
BEGIN
a := b; (* ok *)
pa := pb; (* error, ибо PA&PB - это не записи *)
END
-
Замечу, что это место в Обероне-07/11 отличается от того что в Обероне-89/90. Там было так:
The type of the expression must be included by the type of the variable, or it must extend the type
of the variable.
А стало так:
The type of the expression must be the same as that of the designator.
То есть если раньше у типов была иерархия (одни в другие включались), то теперь все, никакой иерархии, типы должны точно совпадать во всех случаях, кроме RECORD-типов и массивов символов. Указатели, всякие численные типы и так далее, теперь в пролете.
-
А разве
3. In the case of records, the type of the source must be an extension of the type of the destination
не подходит к предыдущему сообщению?
-
А разве
3. In the case of records, the type of the source must be an extension of the type of the destination
не подходит к предыдущему сообщению?
Нет. В сообщении о языке явно различают тип указателя на запись и сам тип-запись.
-
Логично предположить, что присваивание разнотиповых указателей в языке Oberon-07/11 допускается, т. к. в языке предусмотрены операции охраны/проверки типа для переменных-указателей, которые были бы лишены всякого смысла. По всей видимости, Вирт просто забыл (в его без малого 80 лет) сделать исключение для указателей в правиле присваивания, ну или решил, что читатель сам догадается))
-
pa := pb; (* error, ибо PA&PB - это не записи *)
pb := pa(PB); здесь понятно зачем явное приведение типов
pa := pb(PA); здесь явное приведение типов тупо для симметрии с предыдущим случаем :)
Тогда уж и для записей надо было также сделать
b := a(B);
a := b(A);
А то как-то непоследовательно...
-
pb := pa(PB); здесь понятно зачем явное приведение типов
pa := pb(PA); здесь явное приведение типов тупо для симметрии с предыдущим случаем :)
Даже если оставить в покое "синатксический оверхед", то тупо для симметрии не катит, потому что оно несимметрично ни разу :) Семантика действий разная. В одном случае оно пытается привести тип, в другом - тип гарантировано будет приведен. Уж если хотелось явного приведения, то должна была быть отдельная синтаксическая форма для каста вверх по иерархии наследования. Причем для записей тоже (для симметрии).
P.S. Вирт просто недоработал описание языка. Ну и ООП заморочки ему, как я понимаю, глубоко фиолетовы. Во всяком случае для текущих задач.
-
pb := pa(PB); здесь понятно зачем явное приведение типов
pa := pb(PA); здесь явное приведение типов тупо для симметрии с предыдущим случаем :)
Даже если оставить в покое "синатксический оверхед", то тупо для симметрии не катит, потому что оно несимметрично ни разу :) Семантика действий разная. В одном случае оно пытается привести тип, в другом - тип гарантировано будет приведен.
Или не приведен :-)
В первом случае у нас будет рантайм-проверка (dynamic_cast) с возможным трапом в результате. А что будет во втором случае?
Согласно вот этому:
The typeguard v(T0) asserts that v is of type T0, i.e. it aborts program execution, if it is not of type
T0. The guard is applicable, if
1. T0 is an extension of the declared type T of v, and if
2. v is a variable parameter of record type, or v is a pointer.
во втором случае просто не должно скомпилироваться, ибо typeguard не применим в этом случае (для того, чтобы было применимо, необходимо чтобы выполнялись одновременно оба условия (1 и 2), а у нас первое условие не выполняется - у нас не T0 является расширением T, а наоборот).
-
ФИ как все жухло, однако- тратить время которое не вернуть на обсуждение такой х..ни.... не жалко господа?
-
Так полнолуние в разгаре, раз уж клевет новых нет, надо хоть так время потратить...
-
:D А.. ,старый я стал.. ленивый..ужо не возбуждаюсь...