![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
|
|||||
|
Guest
Сообщений: n/a
|
Открываем новый fla и в в Frame Action пишем одну строчку:
foo=0*++1.2345; ... запускаем на выполнение..... Как вы думаете чему будет равна переменная foo? Очевидно - нулю.... Ноль умножить на любое число - ноль... Логично.... Нажимает Ctrl-Alt-V............. и тихонько сползаем со стула....... ............ теперь выбрасывем foo к чёрту... пишем, например ...... 10#++1.23456; где вместо '#' может стоять ЛЮБАЯ операция-'+','-','*','/,'%','<','>','<>','|','&' - результат от этого не меняется..... Запускаем..... Нажимает Ctrl-Alt-V...... Протитаем глаза.... Пауза.......... Вобщем - Очевидное-невероятное..... ![]() |
|
|||||
|
don't panic!
Регистрация: Aug 2001
Сообщений: 4,121
|
все абсолютно правильно
1.2345 - это НЕ леводопустимое выражение (леводопустимое, это которое может стоять слева от знака присвоения) что по сути выполняется если написано ++1 ? – при трансляции все числовые значения в коде являются константами – мы берем константу и увеличиваем ее значение на 1. ну не фигня ли это ? это то же самое что написать: 1 = 2; вот если написать i=1.2345; foo=0*++i; то все в порядке, потому что имя переменной - это леводопустимое выражение... зы: вот мыкс за леводопустимостью следит строго... а пятерка стандарту (как там он называется ?) не соответствует, и ошибку эту выдает, но при компиляции о ней не сообщает... |
|
|||||
|
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 вышеприведённом случае ведёт себя таким непонятным и нелогичным образом !!! В этом-то вся и фигня...... |
|
|||||
|
don't panic!
Регистрация: Aug 2001
Сообщений: 4,121
|
так ты же сам и подтвердил все
![]() проблема в не-леводопустимости выражения 1.2345 - это не "Reference" => "throw a ReferenceError exception". ...и компилятор пятерки не сообщает об ошибке, хотя код после этого работает черт знает как... это вроде евала в левой части... глюк из той же серии... а насчет константы - это просто объяснение того же самого другими словами ![]() 1=2; не смотря ни на что приведет к ошибке, и если это дело замаскировать инкрементом, то это ничего не исправит ![]() |
|
|||||
|
Guest
Сообщений: n/a
|
2Nox Noctis
.... eval в левой части не глюк... Это была возможность возвращать в левой части выражения переменную типа Reference (идентификаторы), что, кстати, допускается стандартом. Зачем эту возможность убрали в MX я пока не понимаю.... ... На самом деле удивляет вот что - согласно грамматике языка допускается возможность некоторой операции (в данном случае ++const), но в АЛГОРИТМЕ РЕАЛИЗАЦИИ этой операции такая конструкция считается недопустимой!!! И как тут жить?? Возникает вопрос - что приоритетней: грамматика или алгоритм реализации этой грамматики???? Мне пока непонятно.... Может кто из гуру объяснит?? |
|
|||||
|
don't panic!
Регистрация: Aug 2001
Сообщений: 4,121
|
грамматика много чего разрешает...
но это всего лишь формальная правильность, а содержательная правильность проверяется либо во мремя компиляции, либо вообще в рантайме... а сравнивать что важнее - форма или содержание, это как-то странно ![]() насчет евала в левой части присвоения : самый верхний пост (john'a) ![]() ...ты видел, кстати, во что транслитруется выражение a = 0*++1.2345; в ассемблерном коде (в сравнении с a = 0*++(b=1.2345); ) ? ...очень забавно ![]() Последний раз редактировалось Nox Noctis; 14.06.2002 в 14:45. |
|
|||||
|
Guest
Сообщений: n/a
|
2Nox Noctis
.... Мда..... Мне эта ситуация напоминает поговорку - "Если нельзя, но очень хочется - то можно"! Или перефразируя для данной ситуации - "Если можно, но очень не хочется - то нельзя"..... Или нашу Конституцию и законы - Конституция (грамматика) вроде бы позволяет.... но законы (алгоритм реализации Конституции) ни фига...... (((.... Ладно.... это уже флэйм и к делу не относится.....Вывод - имеем в Flash 5 законченный БАГ.... Интересно, кстати, Micromedia о нём знает???? ЗЫ во что транслируется данные выражения - видел.... Наверное им можно пугать тех, кто смотрит коды с помощью ASV или SWF Scaner`а..... Кстати, в MX сгенерённый F5 код этой оперции прекрасно выполняется.... Спасибо за дискуссию. С уважением. Suhoff ![]() Последний раз редактировалось Suhoff; 15.06.2002 в 02:57. |
|
|||||
|
don't panic!
Регистрация: 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, время: 11:55. |
|
|
« Предыдущая тема | Следующая тема » |
|
|