Re[2]: Решите тогда задачу
От: Андрей Тарасевич Беларусь  
Дата: 13.11.06 18:18
Оценка: :)
Здравствуйте, Roman Odaisky, Вы писали:

RO>Хорошо, а как «правильно» решить следующую простейшую задачу?


RO>Круг разбит на n > 0 секторов, пронумерованых подряд числами 0, 1, ..., n – 1. Некто стоит в секторе номер 0, затем идет по кругу, делая s шагов. Куда он попадет?


Так а что означают этти загадочные числа "с потолка" в конце таблицы? Это при том-то, что реализации функции не приведено
Best regards,
Андрей Тарасевич
Re[3]: Решите тогда задачу
От: Андрей Тарасевич Беларусь  
Дата: 13.11.06 18:28
Оценка: :)
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, Roman Odaisky, Вы писали:


RO>>Хорошо, а как «правильно» решить следующую простейшую задачу?


RO>>Круг разбит на n > 0 секторов, пронумерованых подряд числами 0, 1, ..., n – 1. Некто стоит в секторе номер 0, затем идет по кругу, делая s шагов. Куда он попадет?


АТ>Так а что означают эти загадочные числа "с потолка" в конце таблицы? Это при том-то, что реализации функции не приведено


А, понял. Это правильные результаты, а не "с потолка"...

И все таки интересно, какую связь этой задачи с данной дискуссией видит автор?
Best regards,
Андрей Тарасевич
Re[4]: Где тут ошибка
От: Андрей Тарасевич Беларусь  
Дата: 13.11.06 19:26
Оценка:
Здравствуйте, Erop, Вы писали:

E>1) реально size таким большим не бывает, так как в память плохо помещается


Ни предел типа 'size_t', ни предел типа 'int' никак не связаны с "помещаемостью в память".
Best regards,
Андрей Тарасевич
Re[7]: Нужен ли unsigned
От: Андрей Тарасевич Беларусь  
Дата: 13.11.06 19:58
Оценка:
Здравствуйте, Centaur, Вы писали:

АТ>>Отдельно, кстати, стоит заметить, что, несмотря на то, что большая часть машинных арифметических операций на популярных арихитектурах не требуют различения знаковых и беззнаковых типов, такие требования языков С/С++, как округление у нулю при целочисленном делении, зачастую таки приводят к генерации менее эффективного кода для знаковых типов.


C>В C++ такого требования в общем случае нет. Оно есть для положительных делимого и делителя; в противном случае поведение implementation-defined (C++03 5.6/4). В C — да, округление к нулю (C99 6.5.5/6).


Да, это так (С++ тем не менее неформально рекомендует придерживаться округления к нулю), но опять же это означает что в общем случае этот эффект имеет место.
Best regards,
Андрей Тарасевич
Re[2]: Нужен ли unsigned
От: Michael7 Россия  
Дата: 13.11.06 20:07
Оценка: +1
Здравствуйте, Шахтер, Вы писали:


Ш>1) Беззнаковая арифметика имеет точно определённую семантику, в отличии от знаковой.


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

Ш>2) В беззнаковой арифметике лего ловить переполнение.


Ш>
Ш>unsigned a=...;   
Ш>unsigned b=...;

Ш>a+=b;

Ш>if( a<b ) 
Ш>  { //overflow  
Ш>   ... 
Ш>  }
Ш>


Код изящен и эффективен, но думаю может привести к неприятным трудноуловимым ошибкам. В стандарте C99 результат целочисленного переполнения UB, как в C++2003 стандарте менее ясно, там как-то закручено по-моему.
По-моему, очевидно и то, что результат может зависеть как от архитектуры компьютера, так и даже от компилятора и остального кода. Даже в случае x86 процессора после переполнения выставляется флаг C (carry flag) и нет никакой уверенности в том, как он используется остальным сгенерированным кодом. Признаться я не знаю примера, когда подобный код привёл бы к ошибке, но чисто теоретически полагаю его небезопасным.

Ш>3) В C/C++ размерности массивов выражаются беззнаковым типом size_t. По этой причине ипользовать для индексирования знаковые типы -- создавать потенциальные дыры.


В этом случае может быть. Если очень большие массивы.

Ш>4) LUT удобнее делать с беззнаковыми типами. Классический пример.


Ш>
Ш>bool CharIsXXX(char c)
Ш> {
Ш>  static const bool table[256]={...};

Ш>  return table[(unsigned char)c];
Ш> }

Ш>


Ну так и я не противлюсь везде и всюду беззнаковым типам. Иногда они к месту, как здесь. Но не для случаев, когда просто некая вычисляемая сущность не может быть отрицательной.
Re[3]: Нужен ли unsigned
От: Андрей Тарасевич Беларусь  
Дата: 13.11.06 20:22
Оценка: 4 (2) +2
Здравствуйте, Michael7, Вы писали:


Ш>>1) Беззнаковая арифметика имеет точно определённую семантику, в отличии от знаковой.


M>Вы не могли бы пояснить, потому что мне представляется, что это архитектурно зависимо.


Нет. Какая-то свобода представления значений целых чисел в С/С++ имеется только для знаковых типов. Для беззнаковых все жестко. (Кроме диапазонов, разумеется).

Ш>>2) В беззнаковой арифметике лего ловить переполнение.


Ш>>
Ш>>unsigned a=...;   
Ш>>unsigned b=...;

Ш>>a+=b;

Ш>>if( a<b ) 
Ш>>  { //overflow  
Ш>>   ... 
Ш>>  }
Ш>>


M>Код изящен и эффективен, но думаю может привести к неприятным трудноуловимым ошибкам. В стандарте C99 результат целочисленного переполнения UB, как в C++2003 стандарте менее ясно, там как-то закручено по-моему.


Результат знакового целочисленного переполнения — UB. Беззнаковые типы реализуют арифметику по модулю, т.е. у них не бывает "переполнения" или, другими словами, традиционное переполнение у них приводит к однозначно оговоренному эффекту без какого-либо UB.

M>По-моему, очевидно и то, что результат может зависеть как от архитектуры компьютера, так и даже от компилятора и остального кода.

M>Даже в случае x86 процессора после переполнения выставляется флаг C (carry flag) и нет никакой уверенности в том, как он используется остальным сгенерированным кодом.

Нет. Уверенность есть. На уровне языка. Если "остальной код" начинает как-то неадекватно реагировать на CF в этом случае, или это начинает зависеть от архитектуры, или от компилятора, то все это — глюки компилятора. Но речь не об этом.
Best regards,
Андрей Тарасевич
Re[4]: Нужен ли unsigned
От: Michael7 Россия  
Дата: 13.11.06 21:11
Оценка: 7 (2) +3
Здравствуйте, Андрей Тарасевич, Вы писали:

M>>Чем? На мой взгляд существует очень ограниченный перечень случаев, когда unsigned оправдан, это флаги, коды значений, работа с памятью, может ещё пара случаев и всё. В принципе, ещё можно даже для арифметических операций, если не хватает диапазона значений знакового типа, но это уже грязный стиль и нежелательно.


АТ>Чем — это очень странный вопрос. Беззнаковые по своей природе сущности естественно представлять беззнаковыми типами. Тут, собственно, и вопросов никаких нет.


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

И, разумеется, это не догма. Если их применением достигается меньше ошибок и душевный комфорт программиста или например, вычисления получаются быстрее или компактнее код с беззнаковыми типами и это важно для программы, то применять надо беззнаковый тип.

Просто мой подход, что пока они не требуются их и не использовать.

АТ> И в большинестве случаев оказывается, что знаковые типы просто-напросто чаще "прощают" беспечное отношение к коду.


Что вы считаете в данном контексте безпечностью?

АТ> Во-первых, я считаю, что правильнее внимательнее относиться к коду, а не пытаться компенсировать лень использованием знаковых типов. Во-вторых, "безопасность" знаковых типов — не более чем иллюзия.


Понятно, что по-большому счёту безопасность кода не зависит от знаковости типа. Есть куча более серьёзных проблем. Полагаю Кернигана и Ритчи ещё не раз вспомнят "тихим незлым словом" за строки с нулём на конце от которых даже в C++ далеко не всегда удаётся уйти.

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

АТ>Делать из этого вывод о каких-то недостатках беззнаковых типов — это примерно то же самое, что пытаться писать Паскаль-код на языке С++, и, потерпев неудачу, заявлять, что это свидетельствует о недостатках языка С++.


Да нет недостатков у беззнаковых типов, как и у знаковых. А есть не всегда оправданное их применение, причём я думаю, что применять беззнаковые типы надо реже, чем это многими принято.

M>>Например, казалось бы логично сделать индекс/счётчик беззнаковым, но в дальнейшем может оказаться, что проще всего присваивать ему отрицательные значения для обработки особых ситуаций.


АТ>А вот это — идеологически неправильно.


Как сказать. Писал я как-то код для почти (были там некоторые извращения с перестановками и вставками) FIFO очереди , вполне ничего пошло принять отрицательный индекс начала для пустой очереди, а индекс хвоста в ноль с принудительным выставлением в (-1,0) после обработки последнего элемента. А отдельный признак заводить не хотелось.

AT> Так что говорить, что беззнаковые типы создают какие-то присущие именно им проблемы -совершенно неверно. Это не проблемы знаковых типов. Это соврешенно нормальная реальность программирования на С/С++ к которой рано или поздно все равно придется привыкать. А вот упоминающаяся тут манера безусловного использования знаковых типов — это не более чем попытка убежать от этой реальности.


Ещё раз повторю, что я не говорю о безусловном использовании, а скорее о приоритетном. То есть я воспринимаю беззнаковый тип как более сложный. Не в смысле структуры или реализации, где он как раз проще, а в смысле близости к человеческому восприятию.

P.S. Перечитал сообщение и стало где-то даже смешно, как бы не чересчур серьёзно мы обсуждаем довольно незначительные в общем-то аспекты программирования.
Re[4]: Нужен ли unsigned
От: remark Россия http://www.1024cores.net/
Дата: 13.11.06 21:11
Оценка: 24 (5) +4
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Беззнаковые по своей природе сущности естественно представлять беззнаковыми типами. Тут, собственно, и вопросов никаких нет.


Я всеми руками за типизацию. Если у переменной только два значения, то надо использовать bool, а не int. Если значение не меняется, то надо использовать const. Это замечательно, когда компилятор отлавливает ошибки. Это надо использовать всегда. Всегда, за исключением одного случая. Не надо использовать unsigned. Почему? Из-за реализации в языке. Проблема в том, что компилятор не отловит ошибки. Ну не отловит он и всё. И это получается ещё хуже, т.к. появляется чувство ложной уверенности. Думаешь, я завёл unsigned — всё, все мои проблемы решены. А на самом деле ничего не решено и компилятор практически ничего не контролирует.

Я могу, конечно, поприводить примеры типа таких:

    unsigned u = 0;
    int i = 0;
    u = i;
    i = u;
    // msvc80sp1 уровень предупреждений 4 — ни одного варнинга. Хотя оба из присваиваний могут вызвать проблемы...


    std::vector<int> v (3);
    for (size_t i = v.size() - 1; i >= 0; --i)
        std::cout << v[i];


Или вот ещё статья недавно проскакивала.

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

Фразы типа:

я считаю, что правильнее внимательнее относиться к коду, а не пытаться компенсировать лень использованием знаковых типов

Это из идеального мира. Действительно, давайте просто внимательно писать программы без ошибок.
В реальном мире, к сожалению, не так. Программисты работают по вечерам, по 12 часов, в спешке и т.д. Все мы писали и одинарное равно в if'е вместо двойного, и код типа примера выше и т.д. И очень бы хотелось, что бы при написании программ не надо было проявлять чудеса внимательности и памяти.

знаковые типы просто-напросто чаще "прощают" беспечное отношение к коду


Знаковые типы не просто прощают беспечное отношение к коду, они действительно заставляют больше кода работать корректно. Почувствуйте разницу. Посмотрите на цикл вверху. Что бы заставить его работать достаточно просто заменить size_t на int. Всё. Код будет корректным и рабочим.

Посмотрите пример в статья. Всё что достаточно сделать, что бы там код заработал. Правильно. Заменить unsigned на int.

Работу этого кода сломало единственное — замена signed на unsigned. Причём тоже из благих намерений. В цикле мы по каким индексам хотим пробежать? От size()-1 до 0. Может быть отрицательным? Нет. Заменяем signed на unsigned — код перестаёт работать!

В примере в статье процент в каком диапазоне может быть? От 0 до 100. Может быть отрицательным? Нет. Заменяем signed на unsigned — код (опять) перестаёт работать!

Я думаю таких примеров можно найти ещё.

Обратных же примеров, когда замена unsigned на signed ломает код, нет!
Если не считать, что у unsigned чуть больше диапазон. Но стоит ли оно того? Если уж надо хранить действительно большие числа, то имхо лучше воспользоваться int64_t. Тут и диапазон действительно больше, чем у int и проблем не будет.


Я недавно думал над этим вопросом. И изначально тоже отталкивался от точки, что всё должно быть максимально типизировано. И что надо использовать unsigned. Но потом после анализа таких примеров и кучи блогов, статей, постов по поводу ошибок связанных с unsigned, пришёл к указанному выводу — типизация везде, кроме unsigned. Ну не работает оно так как хочется. Не работает.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Нужен ли unsigned
От: Michael7 Россия  
Дата: 13.11.06 21:22
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Результат знакового целочисленного переполнения — UB. Беззнаковые типы реализуют арифметику по модулю, т.е. у них не бывает "переполнения" или, другими словами, традиционное переполнение у них приводит к однозначно оговоренному эффекту без какого-либо UB.


Да? Я загляну в стандарт и ещё раз перечитаю.

АТ>Нет. Уверенность есть. На уровне языка.


Хм. Буду перечитывать. Если так, то зря я раскритиковал пример.
Re[5]: Статья с примером ошибки
От: Пётр Седов Россия  
Дата: 13.11.06 23:52
Оценка:
Здравствуйте, remark, Вы писали:
R>Или вот ещё статья недавно проскакивала.
Статья "Built-in Type Safety?", автор Thomas Guest. Обсуждали статью здесь
Автор: eao197
Дата: 12.10.06
.
Пётр Седов (ушёл с RSDN)
Re[6]: Всё очень просто....
От: night beast СССР  
Дата: 14.11.06 05:07
Оценка:
Здравствуйте, Erop, Вы писали:

NB>>у беззнаковых чисел есть одно хорошее свойство -- все арифметические операции делаются по модулю.

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

E>Поясни что ты имеешь в виду под этим "хорошим" свойством.


здесь
Автор: Шахтер
Дата: 13.11.06


E>и от чего оно таки хорошее?


отсутствием UB
например твой код для swap'a двух беззнаковых будет рабочим
Re[5]: Нужен ли unsigned
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 14.11.06 06:14
Оценка:
Добавлю ещё чуть-чуть: нет функций преобразования С-строк к unsigned типам. Есть atoi, atol, atoi64. И ни одного unsigned.
Re[6]: Нужен ли unsigned
От: Андрей Тарасевич Беларусь  
Дата: 14.11.06 06:23
Оценка: +1 -1 :)
Здравствуйте, Nuzhny, Вы писали:

N>Добавлю ещё чуть-чуть: нет функций преобразования С-строк к unsigned типам. Есть atoi, atol, atoi64. И ни одного unsigned.


Неверно. 'atoi' и иже с ними — функции "мертвые" и практической ценности не представляющие. Немножко "живее" — 'sscanf', который поддерживает unsigned, но и тот, к сожалению, неполноценен. Настоящие функции преобразования строк к целым из библиотеки С — 'strtol' и 'strtoul' (плюс 'll' версии в С99), из которых последняя как раз unsigned.
Best regards,
Андрей Тарасевич
Re[7]: Нужен ли unsigned
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 14.11.06 07:21
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, Nuzhny, Вы писали:


N>>Добавлю ещё чуть-чуть: нет функций преобразования С-строк к unsigned типам. Есть atoi, atol, atoi64. И ни одного unsigned.


АТ>Неверно. 'atoi' и иже с ними — функции "мертвые" и практической ценности не представляющие. Немножко "живее" — 'sscanf', который поддерживает unsigned, но и тот, к сожалению, неполноценен. Настоящие функции преобразования строк к целым из библиотеки С — 'strtol' и 'strtoul' (плюс 'll' версии в С99), из которых последняя как раз unsigned.


Совсем мёртвые? А я для С-строк ими пользуюсь...
Надо переходить на std::num_get<>::get().
Re[10]: Не! проще таки лучше!
От: Erop Россия  
Дата: 14.11.06 09:26
Оценка: 3 (1) +1 -1
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Во-первых, в STL — это необходимость реализации именно абстракций. Поэтому стали пользоваться новыми добрыми простыми и надёжными способами. И они, похоже, даже добрее, проще и недежней. Что делает осмысленным из использование и за пределами STL.


АТ>Во-вторых, к STL все это отностся на самом деле мало. Эти "абстакции" зарыты намного глубже.


АТ>(Причины приведения примеров не совсем понятны).


Плохо, что не понятны.
Я предалагаю STL подробно не обсуждать. просто, АФАИК идеи о unsigned индексах и размерах массивов появились вместе с изобретением STL.

Ну а с тем, что "эти абстракции" зарыты намного глубже я тоже совершенно согласен.
про то и вопрос. От чего в языке фортран или там паскаль массивы было удобно итерировать знаковым индексом, а в C++ + STL стало так трудно и опасно?


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

После этого ты стал утверждать, что раз уж в STL-way (через указатели и итераторы) итерации лишний шаг делать нельзя, то не надо приучаться к такой возможности при итерации через индекс.

А я во делаю совершенно противоположенный вывод. Раз уж в STL-way делать "лишний шаг" опасно, а часто хочется, то это косяк STL-way.
Возможно у этого пути естьи плюсы, но конкретно это -- минус. Косяк, провоцирующий ошибки. Для того, чтобы избежать их, предлагается писать все итерации массивов через unsigned индекс. Мне кажется, что лучше избегать STL-way итерации.

Забавно, кстати, что сами авторы STL пожоже это тоже чувствовали. Потому что понаписали всяких for_each
В принципе я их понимаю. Так как простой for() при использовании итераторов и unsigned индексов действительно становится неудобным и опасным
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Нужно искать внимательнее, товарищ эксперт!
От: Erop Россия  
Дата: 14.11.06 09:33
Оценка: :)
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Конечно, лучше! Вот только где бы найти такой оптимизатор... Т.е. ясно, что нет такого оптимизатора и быть не может, но все равно — лучше бы он...


А какие проблемы с принципиальным существованием такого оптимизатора?

Ведь в коде


int i;
int size;
assert( 0 <= size );

if( 0 <= i && i < size ) {
    Do1();
}

if( unsigned( i ) < unsigned( size ) ) {
    Do2();
}


Do1() и Do2() будут всегда вызываться одновременно.
Так что условия в if'ах совершенно эквивалентны. только перове условие понятнее.

при этом оптимизатор занет переносима такая оптимизация или нет
О том, что в большинстве случаев это будет ещё и преждевременная оптимизация я скромно стараюсь не вспоминать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Где тут ошибка
От: Erop Россия  
Дата: 14.11.06 09:39
Оценка: 1 (1) +1
Здравствуйте, Андрей Тарасевич, Вы писали:

E>>1) реально size таким большим не бывает, так как в память плохо помещается

АТ>Ни предел типа 'size_t', ни предел типа 'int' никак не связаны с "помещаемостью в память".

Ну в программировании вообще всё задачами определяется. Область деятельности-то прагматическая
Вот в обсуждаемой задаче -- итерации массива, мало есть возможностей завести такой массив, чтобы знаково/беззнаковые дыры сказались
А в каком-то абстрактном вычислительном алгоритме использовать для итерации unsigned, КМК, себе дороже.
Скажем для итерации слоёв в вычислительной схеме. Таки из номера слоя что-нибудь вычитать иногда хочется
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: Нужен ли unsigned
От: Erop Россия  
Дата: 14.11.06 09:48
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Неверно. 'atoi' и иже с ними — функции "мертвые" и практической ценности не представляющие.

А почему?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Нужен ли unsigned
От: Кодт Россия  
Дата: 14.11.06 09:54
Оценка: 7 (1) +1
Здравствуйте, remark, Вы писали:

Практически согласен со всем, кроме вот этого

R>Обратных же примеров, когда замена unsigned на signed ломает код, нет!

R>Если не считать, что у unsigned чуть больше диапазон. Но стоит ли оно того? Если уж надо хранить действительно большие числа, то имхо лучше воспользоваться int64_t. Тут и диапазон действительно больше, чем у int и проблем не будет.

Как только мы начинаем упражняться в работе с битами, проблемы сразу же появляются.
— приведение типов (всем хорошо известно, как переводить char в int: (int)(unsigned char)ch)
— сдвиг (SHR для беззнаковых и SAR для знаковых)
— битовые поля
struct bitz
{
    unsigned u : 1; // принимает значения 0 и 1
    int      i : 1; // принимает значения... сюрприз! 0 и -1, потому что старший (единственный) бит - знаковый
};
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: Решите тогда задачу
От: Roman Odaisky Украина  
Дата: 14.11.06 10:51
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>И все таки интересно, какую связь этой задачи с данной дискуссией видит автор?


А ты попробуй ее реши

Хинт:
-1 % 10 = -1
-1 % 10u = 5
(хотя хотелось бы видеть 9)

Как эту задачу решить правильно, я затрудняюсь сказать. В псевдокоде она решается одной строчкой:
unsigned f(unsigned n, int s)
{
    return s % n;
}
но правила C/C++ чуть изменяют поведение оператора % (по сравнению с математической его версией), в результате чего всё становится с ног на голову.
До последнего не верил в пирамиду Лебедева.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.