Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Архив Flasher.ru > Flash > ActionScript

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему  
Старый 13.06.2002, 01:42
  № 1  
Suhoff
Guest

Сообщений: n/a
По умолчанию Занимательный ActionScript (Flash 5 only!!)

Открываем новый fla и в в Frame Action пишем одну строчку:

foo=0*++1.2345;

... запускаем на выполнение.....
Как вы думаете чему будет равна переменная foo? Очевидно - нулю.... Ноль умножить на любое число - ноль... Логично....
Нажимает Ctrl-Alt-V............. и тихонько сползаем со стула.......
............
теперь выбрасывем foo к чёрту... пишем, например ......

10#++1.23456;

где вместо '#' может стоять ЛЮБАЯ операция-'+','-','*','/,'%','<','>','<>','|','&' - результат от этого не меняется.....
Запускаем..... Нажимает Ctrl-Alt-V...... Протитаем глаза.... Пауза..........
Вобщем - Очевидное-невероятное.....

Старый 13.06.2002, 02:58
Nox Noctis вне форума Посмотреть профиль Отправить личное сообщение для Nox Noctis Посетить домашнюю страницу Nox Noctis Найти все сообщения от Nox Noctis
  № 2  
Nox Noctis
don't panic!
 
Аватар для Nox Noctis

Регистрация: Aug 2001
Сообщений: 4,121
все абсолютно правильно

1.2345 - это НЕ леводопустимое выражение
(леводопустимое, это которое может стоять слева от знака присвоения)

что по сути выполняется если написано ++1 ?
– при трансляции все числовые значения в коде являются константами
– мы берем константу и увеличиваем ее значение на 1.
ну не фигня ли это ?

это то же самое что написать:
1 = 2;

вот если написать
i=1.2345;
foo=0*++i;
то все в порядке, потому что имя переменной - это леводопустимое выражение...

зы: вот мыкс за леводопустимостью следит строго... а пятерка стандарту (как там он называется ?) не соответствует, и ошибку эту выдает, но при компиляции о ней не сообщает...

Старый 13.06.2002, 04:17
  № 3  
Suhoff
Guest

Сообщений: n/a
2Nox Noctis
...Почему фигня то, что "мы берём константу и увеличиваем её значение на 1", я не понимаю....
А по поводу того, что 1.2345 не является леводопустимым выражением..... Давайте возьмём стандат ECMA-262 (он ТАК называется) и рассмотрим следующую цепочку из описания грамматики языка.....

UnaryExpression :
PostfixExpression
delete UnaryExpression
void UnaryExpression
typeof UnaryExpression
++ UnaryExpression
-- UnaryExpression
+ UnaryExpression
- UnaryExpression
~ UnaryExpression
! UnaryExpression

PostfixExpression :
LeftHandSideExpression
..............................................................

LeftHandSideExpression :
NewExpression
CallExpression

NewExpression :
MemberExpression
new NewExpression

MemberExpression :
PrimaryExpression
FunctionExpression
MemberExpression [ Expression ]
MemberExpression . Identifier
new MemberExpression Arguments

PrimaryExpression :
this
Identifier
Literal
ArrayLiteral
ObjectLiteral
( Expression )

Literal ::
NullLiteral
BooleanLiteral
NumericLiteral
StringLiteral

а 1.2345 - по сути является NumericLiteral...........

Это с одной стороны... С другой стороны...
Постфиксный инкримент выполнятеся согласно стандарту следующим образом-
11.4.4 Prefix Increment Operator
The production UnaryExpression : ++ UnaryExpression is evaluated as follows:
1. Evaluate UnaryExpression.
2. Call GetValue(Result(1)).
3. Call ToNumber(Result(2)).
4. Add the value 1 to Result(3), using the same rules as for the + operator (see 11.6.3).
5. Call PutValue(Result(1), Result(4)).
6. Return Result(4).
..............................................
8.7.2 PutValue (V, W)
1. If Type(V) is not Reference, throw a ReferenceError exception.
2. Call GetBase(V).
3. If Result(2) is null, go to step 6.
4. Call the [[Put]] method of Result(2), passing GetPropertyName(V) for the property name and W for
the value.
5. Return.
6. Call the [[Put]] method for the global object, passing GetPropertyName(V) for the property name and
W for the value.
7. Return.

Поскольку Численный литерал не имеет тип "Reference" (его имеют идентификаторы), то "++1.2345" должно выдавать "ReferenceError exception.", чего не происходит...

А происходит то, что Flash 5 вышеприведённом случае ведёт себя таким непонятным и нелогичным образом !!!
В этом-то вся и фигня......

Старый 13.06.2002, 07:07
Nox Noctis вне форума Посмотреть профиль Отправить личное сообщение для Nox Noctis Посетить домашнюю страницу Nox Noctis Найти все сообщения от Nox Noctis
  № 4  
Nox Noctis
don't panic!
 
Аватар для Nox Noctis

Регистрация: Aug 2001
Сообщений: 4,121
так ты же сам и подтвердил все
проблема в не-леводопустимости выражения 1.2345 - это не "Reference" => "throw a ReferenceError exception".
...и компилятор пятерки не сообщает об ошибке, хотя код после этого работает черт знает как... это вроде евала в левой части... глюк из той же серии...

а насчет константы - это просто объяснение того же самого другими словами
1=2; не смотря ни на что приведет к ошибке, и если это дело замаскировать инкрементом, то это ничего не исправит

Старый 14.06.2002, 02:00
  № 5  
Suhoff
Guest

Сообщений: n/a
2Nox Noctis
.... eval в левой части не глюк... Это была возможность возвращать в левой части выражения переменную типа Reference (идентификаторы), что, кстати, допускается стандартом. Зачем эту возможность убрали в MX я пока не понимаю....
... На самом деле удивляет вот что - согласно грамматике языка допускается возможность некоторой операции (в данном случае ++const), но в АЛГОРИТМЕ РЕАЛИЗАЦИИ этой операции такая конструкция считается недопустимой!!! И как тут жить?? Возникает вопрос - что приоритетней: грамматика или алгоритм реализации этой грамматики????
Мне пока непонятно....
Может кто из гуру объяснит??

Старый 14.06.2002, 14:44
Nox Noctis вне форума Посмотреть профиль Отправить личное сообщение для Nox Noctis Посетить домашнюю страницу Nox Noctis Найти все сообщения от Nox Noctis
  № 6  
Nox Noctis
don't panic!
 
Аватар для Nox Noctis

Регистрация: Aug 2001
Сообщений: 4,121
грамматика много чего разрешает...
но это всего лишь формальная правильность, а содержательная правильность проверяется либо во мремя компиляции, либо вообще в рантайме...

а сравнивать что важнее - форма или содержание, это как-то странно

насчет евала в левой части присвоения : самый верхний пост (john'a)


...ты видел, кстати, во что транслитруется выражение a = 0*++1.2345; в ассемблерном коде
(в сравнении с a = 0*++(b=1.2345); ) ?
...очень забавно


Последний раз редактировалось Nox Noctis; 14.06.2002 в 14:45.
Старый 15.06.2002, 02:55
  № 7  
Suhoff
Guest

Сообщений: n/a
2Nox Noctis
.... Мда..... Мне эта ситуация напоминает поговорку - "Если нельзя, но очень хочется - то можно"! Или перефразируя для данной ситуации - "Если можно, но очень не хочется - то нельзя"..... Или нашу Конституцию и законы - Конституция (грамматика) вроде бы позволяет.... но законы (алгоритм реализации Конституции) ни фига...... (((.... Ладно.... это уже флэйм и к делу не относится.....
Вывод - имеем в Flash 5 законченный БАГ.... Интересно, кстати, Micromedia о нём знает????

ЗЫ во что транслируется данные выражения - видел.... Наверное им можно пугать тех, кто смотрит коды с помощью ASV или SWF Scaner`а..... Кстати, в MX сгенерённый F5 код этой оперции прекрасно выполняется....

Спасибо за дискуссию.
С уважением. Suhoff


Последний раз редактировалось Suhoff; 15.06.2002 в 02:57.
Старый 15.06.2002, 03:33
Nox Noctis вне форума Посмотреть профиль Отправить личное сообщение для Nox Noctis Посетить домашнюю страницу Nox Noctis Найти все сообщения от Nox Noctis
  № 8  
Nox Noctis
don't panic!
 
Аватар для Nox Noctis

Регистрация: Aug 2001
Сообщений: 4,121
обращайтесь...


напоследок я все-таки приведу этот кусочек кода c ошибкой... мало ли кому интересно...

из выражения a = 0*++1.2345; при трансляции получается:

push 'a', 0.0, 1.2345
increment
setRegister r:0
setVariable
push r:0
multiply
setVariable


расшифруем:

push 'a', 0.0, 1.2345 // имя и два числа заносиятся в стэк
increment // операция берет верхнее в стэке значение и увеличивает его на 1 прямо в стэке (т е 1.2345+1)
setRegister r:0 // в регистр r0 помещаем верхнее в стэке значение (т е 2.2345)
setVariable // берем последнее в стэке значение и запихиваем его в переменную с именем равному предпоследнему в стэке значению (в данном случае 0.0 = 2.2345 - уже хорошо ) после присвоения операнды из стэка удаляются
push r:0 // заносим в стэк то, что до этого положили в регистр r0 (это было 2.2345)
multiply // перемножаем два оставшихся в стэке операнда (то есть 'a'*2.2345 ) и результат кладем в стэк...
setVariable // проделываем такую же операцию как см. выше... но учитывая, что в стэке у нас всего один операнд в данный момент (да и тот пустой ) - получаем полную лажу


Последний раз редактировалось Nox Noctis; 15.06.2002 в 03:42.
Создать новую тему   Часовой пояс GMT +4, время: 13:34.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 13:34.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.