Имя: Пароль:
1C
 
Тайна пустого значения переменной
0 Chai Nic
 
07.12.09
15:12
Процедура Сформировать()
   Перем П2;
   
   П1=456;
   
   П3=П2/(П1+П2);
   
   Сообщить(П2/5);
   Сообщить("П1="+Строка(П1));
   Сообщить("П2="+Строка(П2));
   Сообщить("П3="+Строка(П3));
КонецПроцедуры

Результат работы процедуры:
---
П1=456
П2=
П3=456
---

Неинициализированная переменная весьма странно себя ведет в выражениях, она не превращается ни в ноль ни в пустую строку. И не выдает ошибки. Почему?
1 skunk
 
07.12.09
15:16
потому как вариант
2 Ненавижу 1С
 
гуру
07.12.09
15:19
тайна сия велика, ибо 7.7
3 Ненавижу 1С
 
гуру
07.12.09
15:20
+(2) хотя не только
4 vde69
 
07.12.09
15:22
наберут студентов которые с нормальной типизацией не работали ни разу....

Неинициализированная переменная  -  имеет неопределенный тип, вот и все
5 smaharbA
 
07.12.09
15:24
П3=456
не думал
6 skunk
 
07.12.09
15:25
(4)сдается мне, что тогда бы эсина валилался по ошибке 80020008
7 Chai Nic
 
07.12.09
15:25
(4) То что неопределенный тип, это понятно. Непонятно, почему присутствие этого типа в выражениях не выдает ошибку, а весьма странно учитывается.
8 Ненавижу 1С
 
гуру
07.12.09
15:30
(7) неочевидные способности с неочевидными данными
9 vde69
 
07.12.09
15:32
(7) нормально учитывается, просто 1с не знает как этот тип отобразить в отладчике.... вообще все обьекты в 1с имеют тип variant , посмотри как ведет себя 1с с любым OLE обьектом....
10 Ненавижу 1С
 
гуру
07.12.09
15:33
(9) ну и почему П3=456 ?
11 Chai Nic
 
07.12.09
15:37
(9) Не только в отладчике, а вообще в среде исполнения. А если 1с не знает - нафига фантазировать? Выдавала бы ошибку.
12 Злопчинский
 
07.12.09
15:51
Если просто написать
ааа = ааа/0 - то даже исключительной ситуации не будет
13 vde69
 
07.12.09
15:52
(11) тогда пришлось-бы отказатся от слишком многих упрощений языка
(10) вероятно все операции в 1с реализованы не инструкциями а функциями (что-бы они могли внутри функций приводить типы), и неопределенные параметры там имеют присвоение по умолчанию. Примерно так

функция Разделить(х=1, у=1)
функция Сложить(х=0, у=0)
14 AeDen
 
07.12.09
15:53
(12) Это, м.б., только если ты ааа до этого определишь в блоке описания переменных... А если не определишь - то все, кранты, лови исключение.
15 Злопчинский
 
07.12.09
16:01
(14) умный, да ;-) специально для таких как ты автомобилисты на заднем бампере лепят девиз "Не уверен - не обгоняй".
.
специально для тебя: не поленись ручками открыть конфигуратор и копипасте сделать:
.
//*******************************************
Процедура Сформировать()
   ааа = ааа/0;
КонецПроцедуры
16 Chai Nic
 
08.12.09
07:15
(13) Всё равно ведь глюк. Нормальным поведением было бы корректное автоприведение типов. Скажем, если одно из слагаемых - строка, то второй тоже приводим к строке (для упрощение конкатенаций строки и числа, существующее поведение). Если в операциях умножения или деления участвуют объекты нечислового типа - всегда преобразуем их в число. А здесь - прямо как в микрокалькуляторе МК-52 с ЕГГОГами :)
17 Rie
 
08.12.09
07:18
(16) Тебе их корректно автопривели в (0). Чем недоволен?
18 Chai Nic
 
08.12.09
07:20
(17) Как это? Расшифруйте плиз. Сначала для сложения, потом для деления.
19 Rie
 
08.12.09
07:22
(18) А что ты понимаешь под "корректным автоприведением"?
20 Рэйв
 
08.12.09
07:24
А мне кажется в эске математические операторы перегружены так, что если переменная не инициализированна, то используетися 1.
21 Chai Nic
 
08.12.09
07:26
(19)
Корректное - это в первую очередь документированное.
Или хотя бы очевидное.
(20) Ну попробуйте посчитать П3 по этим правилам, получится у вас 456?
22 skunk
 
08.12.09
07:27

var intWhat1;
intWhat2 = 459;
intWhat3 = intWhat2/intWhat1;


получаем

intWhat3 = intWhat2/intWhat1;
{C:\KILL.ERT(5)}: Деление на 0
23 Рэйв
 
08.12.09
07:27
(21)Да, не выходит каменный цветок:)
24 Chai Nic
 
08.12.09
07:30
(22) Вот-вот. Здесь всё правильно.
25 skunk
 
08.12.09
07:30
(21)извините меня ... не подскажете на какой странице мануала я могу прочитать за

число(" ") = 0
число("") = 0
26 Rie
 
08.12.09
07:30
(20) Что за операция (для какого типа) - определяется первым операндом.

Сообщить(Строка(1+"2"+"2");
Сообщить("1"+2+2);
27 skunk
 
08.12.09
07:30
(24)ну а чего тогда голову ломаешь?
28 Chai Nic
 
08.12.09
07:34
(27) Меня удивляет, что некоторые считают указанное в (0) нормальным поведением.
29 Рэйв
 
08.12.09
07:34
(26)По нормальному должно пытаться приводить "2" к 2.т.е. "+" будет браться из класса int.
А во втором из string
30 skunk
 
08.12.09
07:35
(28)привычка ...
31 Песец
 
08.12.09
07:36
(0) При выполнении П3=П2/(П1+П2)
первым выполняется выражение в скобках (П1+П2),
и происходит приведение типа П2 к П1.
32 Chai Nic
 
08.12.09
07:36
(26,29) Да, есть такая лажа с нарушением принципа коммутативности сложения. Зря это сделали. Вариантные типы вещь удобная, но вот с автоприведениями они перемудрили.
33 Chai Nic
 
08.12.09
07:37
(31) О! Давайте по порядку. Какой тип у "неопределено" + число.
34 skunk
 
08.12.09
07:51
(31)точно песец

1 + ("3" + 2) = 33
35 Песец
 
08.12.09
07:55
(33) При невозможности неявного приведения семерка просто молча ничего не делает.

В (15) именно так и происходит: попытка приведния 0 к "неопределено" не получается, и 1С прекращает дальнейшее вычисление выражения, до деления на 0 дело не доходит.

Согласен, это не есть гут. Должно было выскочить сообщение вроде "невозможно преобразовать бла-бла-бла".

ЗЫ: Я всего лишь пытаюсь объяснить поведение 1С в приведенных в этой ветке примерах. Это мое кмк и не более того.
36 Chai Nic
 
08.12.09
07:56
А вот еще забавнее.
---
Процедура Сформировать()
   Перем П2;
   П1=456;
   Врем=П1+П2;
   П3_1=П2/Врем;
   П3_2=П2/(П1+П2);
   Сообщить("П1="+Строка(П1));
   Сообщить("П2="+Строка(П2));
   Сообщить("П3_1="+Строка(П3_1));
   Сообщить("П3_2="+Строка(П3_2));
КонецПроцедуры
---
Результат:
---
П1=456
П2=
П3_1=
П3_2=456
---
37 Песец
 
08.12.09
07:56
(34) Сначала в скобках 2 приводится к строке, получается "3" + "2", вычисляется, получается "32", далее "32" приводится к числу, выполняется 1+32, вычисляется, получаем 33.
38 Chai Nic
 
08.12.09
07:57
"1С прекращает дальнейшее вычисление выражения"
Да, похоже так и есть. Грустно.
39 skunk
 
08.12.09
07:58
(37)по твоей логики тогда бы П3 стало неопределенным ...
40 AcaGost
 
08.12.09
07:59
(29) А ты в курсе, что 7.7 не поддерживает класс "int"
41 Рэйв
 
08.12.09
07:59
(36)>>П2/(П1+П2)
Такое ощущение что любой оператор при неинициализированной левой переменной тупо возвращает правую если она инициализированна
42 Рэйв
 
08.12.09
08:01
(40)Напрямую нет.Но внутри в обертках типов все равно он есть. 1С на сишке написано, насколько я знаю.
43 AcaGost
 
08.12.09
08:03
(42) Сложи два числа максимальных, по разряу "int"
44 Рэйв
 
08.12.09
08:03
+(41)Вернее любую из инициализиваронныз переменных пары
45 Песец
 
08.12.09
08:04
(39) Приведения к неопределенному типу в семерке нет, и попытка такого приведения сразу же приводит (каламбур!) к прекращению вычисления выражения.

Повторюсь, это всего лишь мое предположение.

Вот цитата из ЖКК по правилам приведения типов:

"Строка -> Число
Строка преобразуется в число пока это возможно. Получившееся число счи­тается результатом преобразования. (Например, строка "1.22 Glass" будет преобразована к числу 1.22). Если в начале строки не имеется ничего, что мог­ло бы быть проинтерпретировано как число, то результат равен 0."

Обратите внимание на "...преобразуется ... пока это возможно".
46 Рэйв
 
08.12.09
08:05
(43)При переполнении приводится к double имхо.Если отвязались от жесткой типизации то такие случаи уж должны предусмотреть я думаю
47 skunk
 
08.12.09
08:10
9999999999999999999999999999999999999 + 9999999999999999999999999999999999999

какой тип
48 1Сергей
 
08.12.09
08:12
ТипЗначенияСтр(9999999999999999999999999999999999999 + 9999999999999999999999999999999999999) = Число
49 skunk
 
08.12.09
08:13
(48)незнает компьютер такое тип значения ...
50 Песец
 
08.12.09
08:15
(0)

"Не допускается использование в выражениях переменных с неопределен­ным значением (то есть переменных, которым никогда не присваивалось значе­ния)."

(с) ЖКК.
51 BoBaBo
 
08.12.09
08:18
(50)

перем м;

Процедура Сформировать()
       
   а = 2*м;
   сообщить(а);
   
КонецПроцедуры



результат 0
еще есть вопросы?
52 BoBaBo
 
08.12.09
08:19
перем м;

Процедура Сформировать()
       
   а = 2/м;
   сообщить(а);
   
КонецПроцедуры

результат
err а = 2/м;
{C:\123321.ERT(6)}: Деление на 0
53 Rie
 
08.12.09
08:20
(50) Точность документации у 1С частенько оставляет желать лучшего.
54 skunk
 
08.12.09
08:20
(51),(52)а теперь поменяй местами 2 и "м"
55 Рэйв
 
08.12.09
08:20
(48) Число в 1С это скорее всего что то типа:

class Число
{

 Число(int d){a=d;return a;}
 Число(float d){b=d;return b;}
 Число(double d){c=d;return c;}
 // и т.д.

 private int a;
 private float b;
 private double c;
 // ... и т.д
}
56 skunk
 
08.12.09
08:21
(55)число в 1С это просто вариант... как впрочем и любой другой тип
57 BoBaBo
 
08.12.09
08:22
(54) неопределено
58 Рэйв
 
08.12.09
08:23
(56)Вариант на более низком уровне тоже имхо также разбирает типы, потому что надо же знать сколько памяти резервировть
59 BoBaBo
 
08.12.09
08:23
+(57) однако

перем м;

Процедура Сформировать()
       
   а = Число(м*2);
   сообщить(а);
   
КонецПроцедуры


результат 0
60 Песец
 
08.12.09
08:24
(53) Да, из текста ЖКК складывается впечатление, что платформа не допустит использования неинициализированных переменных.

Надо было написать "Программист не должен допускать ...".
61 skunk
 
08.12.09
08:24
(57)теперь есть вопросы почему запрещено

(58)не фиха он не разбирает... сама эсина гребет с разборами и именно поэтому имем, то что имеем
62 Рэйв
 
08.12.09
08:28
(61)Если 1с написано на Си , то там нет встроенного типа Variant, так что все равно придется как-то заморачиваться типами в конце концов, или писть свой Variant
63 Chai Nic
 
08.12.09
08:29
(60) Скорее всего, предполагалось что платформа должна отследить это и выдать ошибку, но наверное что-то не доделали, и оставили как есть. А в документацию внести поправку забыли.
64 BoBaBo
 
08.12.09
08:30
(63) 1с написана на 1с
65 skunk
 
08.12.09
08:30
(62)еще одну америку открываешь?

тебе ссылки на msdn покидать?
66 BoBaBo
 
08.12.09
08:30
1с 80 на 1с 77, 77 - на 75, 75 -на 70.
эволюция. дарвин.
67 Chai Nic
 
08.12.09
08:31
(64,66) ??? Давайте не превращать тему в стёб.
68 Рэйв
 
08.12.09
08:32
(65)Спасибо:), у меня и так работы много:))
69 Рэйв
 
08.12.09
08:33
+(65)А msdn у меня локально стоит:)
Компьютеры — прекрасное средство для решения проблем, которых до их появления не было.