Re[22]: Что толку в Ада если Ариан 5 все равно упал
От: Трурль  
Дата: 06.07.05 13:06
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Я не готов дать определение термину "метапрограммирование" в его широком смысле — это непростая задача.

Подумаешь, бином Ньютона. Вот, пожалуйста:

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


CX>Но у меня есть определение термину "compile-time метапрограммирование". Это возможность с помощью определенных языковых конструкций изменять поведение компилятора. Подчеркиваю — изменять поведение компилятора, а не конечной программы!

А использование прагм — это "compile-time метапрограммирование"?
Re[19]: Что толку в Ада если Ариан 5 все равно упал
От: Oleg A. Bachin Украина  
Дата: 06.07.05 13:06
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Было преобразование (причем контролируемое!) между 64-битной переменной

C>и знаковой 16-битной. Диапазона значений 16-битный переменной хватало
C>для оригинального датчика, но не для измененного. Из-за переполнения
C>вылетело исключение, которое весело распечаталось в поток управления
C>(узнаю адски-паскалевские решения).

только не надо передергивать! если уж спорите — так спорьте честно!
в делфях стандарное решение — на базе синглетона application на верхнем уровевне ловить ИС и обрабатывать назначенной для этого дела процедуркой ApplicationException.
а вот на сишные привычки — это оооочень смахивает! пихать на стек текст и переменные, а потом разбирайся как хочешь! кроме как в поток через printf с этим мало чего полезного сделаешь.

PS против плюсов ничего не имею, но иногда приходится с плоскими либами работать — наследие еще то!
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Best regards,
Oleg A. Bachin
Re[23]: Что толку в Ада если Ариан 5 все равно упал
От: CrystaX Россия https://crystax.me/
Дата: 06.07.05 13:13
Оценка:
Здравствуйте, Трурль, Вы писали:

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


CX>>Я не готов дать определение термину "метапрограммирование" в его широком смысле — это непростая задача.

Т>Подумаешь, бином Ньютона. Вот, пожалуйста:
Т>

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


В общем смысле да. Но как всегда и во всем, есть нюансы.

CX>>Но у меня есть определение термину "compile-time метапрограммирование". Это возможность с помощью определенных языковых конструкций изменять поведение компилятора. Подчеркиваю — изменять поведение компилятора, а не конечной программы!

Т>А использование прагм — это "compile-time метапрограммирование"?

Нет. Так как а) они не являются языковыми конструкциями и б) жестко задают поведение компилятора без возможности выбора.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[12]: Что толку в Ада если Ариан 5 все равно упал
От: Трурль  
Дата: 06.07.05 13:16
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Сейчас ссылки поднимать некогда, закину завтра. Пока что, посмотри в инете по ключевому слову LSP или Liskov's Substitution Principle. Можно даже поиском по RSDN.

Кажется, Вы не так поняли вопрос. Я не просил объяснить, что такое LSP. Мне интересно где там incompliance?
Re[22]: Что толку в Ада если Ариан 5 все равно упал
От: Oleg A. Bachin Украина  
Дата: 06.07.05 13:17
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>
СГ>MODULE Test;

СГ>  IMPORT StdLog;

СГ>  PROCEDURE Do*;
СГ>    VAR i16: SHORTINT; i64: LONGINT;
СГ>  BEGIN
СГ>    i64 := 1000000000000001L;

СГ>    i16 := SHORT(SHORT(i64));  (* Вот так кастуются от LONGINT к SHORTINT *)

СГ>    StdLog.Int(i64); StdLog.Ln;
СГ>    StdLog.Int(i16); StdLog.Ln
СГ>  END Do;

СГ>END Test.
СГ>

.............
СГ>(* В Oberon 2 типы чуток подругому называются, там HUGEINT — 64, LONGINT — 32, INTEGER — 16, SHORTINT — 8 битов *)

а это что было? если паскаль, то так кастуют только параноики — людям одного каста хватает.
кстати, людям хватаит и без каста, просто будет варнинг. если нужно точное совпадение типов (или каст) специально при объявлении типа указывается что он "строго типизированный" по аналогии explicit в сях.

ЗЫ шо за прывычка по 10 операторов в строку... фе.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Best regards,
Oleg A. Bachin
Re[9]: Что толку в Ада если Ариан 5 все равно упал
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 06.07.05 13:18
Оценка:
Здравствуйте, AVC, Вы писали:

ГВ>>Это наследие C и, кроме того, остаётся открытым вопрос: как конкретно должен быть реализован массив? std::vector<> — то частное решение, хоть и стандартизированное.

AVC>Пока не изобретен лучший вариант, меня вполне устраивает виртовское решение.

Именно поэтому оно должно быть внесено в C++ на уровне языка?

AVC>>>Кроме индекса массива, в Обероне проверяются на NIL указатели и процедурные переменные. (Если они имеют значение, отличное от NIL, то их валидность гарантируется. В том числе — сборщиком мусора.)

ГВ>>Опять таки, проверки на NULL (NIL) по месту вызова нужны не всегда. Точно так же, как и с массивами. Зачастую гораздо проще проверить валидность структур перед началом выполнения алгоритма, чем проверять их при каждом использовании.

AVC>Существует понятие программирования по контракту. (Мейер)

AVC>Главный принцип: не доверяй клиенту (вызывающему коду).

Всё хорошо в своём месте и в своё время. ООП само по себе тоже не всегда адекватно задачам. Так что, принцип программирования по контракту тоже не стоит распространять на все случаи программирования.

AVC>>>Еще иногда требуется проверка динамического типа переменной. Для этого в Обероне достаточно одного сравнения.

ГВ>>А это вообще часто называется ошибкой проектирования.
AVC>Это смотря как и где этим пользоваться.
AVC>В Си++ также есть соответствующие "касты".
Которыми нужно пользоваться с тройной оглядкой.

AVC>В самом первом виртовском Обероне не было присоединенных процедур (=виртуальных функций).

AVC>Полиморфизм работал исключительно благодаря динамическому приведению типа.
AVC>Наверное, поэтому динамическое приведение типа реализовано так эффективно.
AVC>Например (опустив все лишнее):
[...]

Ну, я так понимаю, здесь влияет ещё и модель объектов паскаля, конкретно — строго одиночное наследование.

AVC>>>Вот, пожалуй, и все необходимые проверки в Обероне. Можете видеть сами — все они связаны с безопасностью типов и требуют не более одного-двух (для индекса массива) сравнений.

ГВ>>Угу, но каждый раз...
AVC>Опять-таки оптимизатор может устранить некоторые лишние проверки.
Здесь согласен. Хотя я бы не стал полагаться на оптимизатор...

AVC>>>Этого достаточно, чтобы компилятор гарантировал обращение с переменными только в соответствии с их типом (type safety).

AVC>>>Для исключения ошибок в вычислениях иногда желательны проверки на переполнение и т.п. В этом Оберон не отличается от других языков. Оберон позволяет как использовать, так и отключать подобные проверки. (Лично я против такого отключения.)
ГВ>>В отладочных версиях такие проверки полезны, спору нет. В не-отладочных такие проверки очень круто сажают производительность, особенно при большом количестве разыменований.
AVC>Измерения производительности этого не подтверждают.
Что именно они не подтверждают? Падение производительности? Т.е., цепочка инструкций:

inline T *operator->()
{
  if (!p_) throw IllegalPointer;
    return p_;
}


отработает в общем быстрее, чем:

inline T *operator->()
{
    return p_;
}


?

ГВ>>Средствами C++ можно обойти type safety. Разумность такого решения — отдельный вопрос. Если голова на плечах есть — всмё будет в порядке, если с этим проблема, то runtime проверками дела не поправишь. Приведённый пример с NASA свидетельствует, скорее, не о бенефитах типобезопасности, а о том, что всем в NASA было настолько страшно взять ответственность на себя, что спихнули всё на "неправильную" фичу языка. Т.е., проблема не в языке, а в головах.


AVC>Согласен, что проблема — в головах.

AVC>Потому что именно из голов она попадает в языки.

В огороде бузина, а в трюме акулы...

AVC>Забавно читать, что "средствами C++ можно обойти type safety".

AVC>Где бы найти в Си++ эту самую type safety...
Да есть она там, что тут можно сказать...
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[23]: Что толку в Ада если Ариан 5 все равно упал
От: CrystaX Россия https://crystax.me/
Дата: 06.07.05 13:23
Оценка:
Здравствуйте, raskin, Вы писали:

>> Это как? Свой язык создавать предлагаете?

R>Хотя бы препроцессор. Или диалект Паскаль. Тем, кто не поддержит идею —
R>отдавать сгенерированный код, если надо.

В экую степь унесло! Речь ведь идет о существующих языках.

R>Если можно, приведите пример, что Вы считаете compile-time metaprogramming


Пример приведу на C++ — им владею намного лучше, чем функциональными языками.

template <int A, size_t N>
struct power
{
    static int const result = A * power<A, N - 1>::result;
};

template <int A>
struct power<A, 0> {static int const result = 1;};

int a = power<4, 5>::result;


Пример очень упрощенный, но основная идея в нем видна — вычисления происходит в compile-time, при этом с помощью частичной специализации введено условие, при совпадении с которым компилятор прекращает рекурсию (т.е. изменяет поведение). Ни один аспект этого поведения не попадает в конечный код, вся работа производится компилятором.

>> Здесь куда-то в сторону уехали

R>Про AST? Ну, иногда создавать обобщённый код в его терминах приятней.

Да нет, просто это уже вообще не о метапрограммировании.

>> Каждой задаче — свой инструмент.

R>Да, конечно.. Просто язык удобен, компилятор есть — а stand-alone ещё
R>подумай, как собрать, и окошко для ввода-выводы подумай, как нарисовать.
R>Лень. Пока что.

... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[13]: Что толку в Ада если Ариан 5 все равно упал
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 06.07.05 13:23
Оценка:
Здравствуйте, Трурль, Вы писали:

ГВ>>Сейчас ссылки поднимать некогда, закину завтра. Пока что, посмотри в инете по ключевому слову LSP или Liskov's Substitution Principle. Можно даже поиском по RSDN.

Т>Кажется, Вы не так поняли вопрос. Я не просил объяснить, что такое LSP. Мне интересно где там incompliance?

А... извини, плз.

Например, код, аналогичный вот такому анализу:

    IF msg IS DrawMsg THEN (*draw rectangle r*)
    ELSIF msg IS MarkMsg THEN MarkRectangle(r, msg(MarkMsg).on)
    ELSIF msg IS MoveMsg THEN


часто приводится в описаниях LSP как пример LSP-incompliancy.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[10]: Что толку в Ада если Ариан 5 все равно упал
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 06.07.05 13:26
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ> ... этих "если" может быть вагон помимо индексов


Но почему вагон, ведь всего две (и обе уже решены):
1) Проверка индексов массивов;
2) Проверка правильности приведения/преобразования типов;
что еще-то???

Например, повисшие указатели отсутствуют по причине наличия автоматической сборки мусора, автоматической инициализации (новых) указателей NIL-овым значением, невозможности присвоить указателю неправильное значение. Это же, за исключением сборки мусора, относится и к процедурным переменным.
Re[21]: Что толку в Ада если Ариан 5 все равно упал
От: Oleg A. Bachin Украина  
Дата: 06.07.05 13:28
Оценка:
Здравствуйте, AlexEagle, Вы писали:

E>>>Теперь объясни мне, где же я ошибся в определении причины катастрофы? Главное, что исключение возникло там, где его не ждали.


K_O>>А мне кажется, что главное, что исключение возникло. Потому что софт содержал ошибку.


AE>Категорически не согласен... В делфе легко можно получить исключение сфокусирован невидимый контрол средствами VCL... Бред... Причем апи тоже ругается, но тихо и свою работу все же выполняет...

да, встречал такие програмки... а потом любимое OleDb исключение — Multistep error. потому как эксепшены не кидаем, а коды возврата проверять лень.


AE>Из-за этого я избегаю VCL-ных функций, так как они создают проблемы на пустом месте своими дебильнымим исключениями


бред — твое высказывание! не нравятся исключение — проверяй коды возврата. тут народ за нормальный ООП агитирует, а ты назад в пещеры.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Best regards,
Oleg A. Bachin
Re[14]: Что толку в Ада если Ариан 5 все равно упал
От: Трурль  
Дата: 06.07.05 13:43
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Например, код, аналогичный вот такому анализу:


ГВ>
ГВ>    IF msg IS DrawMsg THEN (*draw rectangle r*)
ГВ>    ELSIF msg IS MarkMsg THEN MarkRectangle(r, msg(MarkMsg).on)
ГВ>    ELSIF msg IS MoveMsg THEN
ГВ>


ГВ>часто приводится в описаниях LSP как пример LSP-incompliancy.


Думаю, не совсем аналогичный.
IF msg IS DrawMsg THEN (* это выполняется для DrawMsg и всех его потомков*)
Re[11]: Что толку в Ада если Ариан 5 все равно упал
От: Cyberax Марс  
Дата: 06.07.05 13:43
Оценка: +3
Сергей Губанов wrote:

> ГВ> ... этих "если" может быть вагон помимо индексов

> Но почему вагон, ведь всего две (и обе уже решены):
> 1) Проверка индексов массивов;
> 2) Проверка правильности приведения/преобразования типов;
> что еще-то???

3) Гонки в MT
4) Deadlock'и в MT
5) Неосвобождение ресурсов
6) Неправильная обработка исключений
7) ....

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[24]: Что толку в Ада если Ариан 5 все равно упал
От: Трурль  
Дата: 06.07.05 13:57
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Пример приведу на C++ — им владею намного лучше, чем функциональными языками.


CX>
CX>template <int A, size_t N>
CX>struct power
CX>{
CX>    static int const result = A * power<A, N - 1>::result;
CX>};

CX>template <int A>
CX>struct power<A, 0> {static int const result = 1;};

CX>int a = power<4, 5>::result;
CX>


А теперь вопрос. В какую максимальную степень можно возвести 4?
Re[25]: Что толку в Ада если Ариан 5 все равно упал
От: CrystaX Россия https://crystax.me/
Дата: 06.07.05 14:03
Оценка:
Здравствуйте, Трурль, Вы писали:

Т>А теперь вопрос. В какую максимальную степень можно возвести 4?


Если речь о глубине рекурсии, то implementation defined. По стандарту (насколько я помню), ограничений нет.
Но какое это имеет отношение к разговору?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[12]: Что толку в Ада если Ариан 5 все равно упал
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 06.07.05 14:03
Оценка:
Здравствуйте, Cyberax, Вы писали:

>> что еще-то???


C>3) Гонки в MT

C>4) Deadlock'и в MT
C>5) Неосвобождение ресурсов
C>6) Неправильная обработка исключений

Спасибо, но порчи памяти от этого не происходит.

Порча памяти может произойти из-за неправильного индекса массива (1) и из-за неправильного преобразования/приведения типа (2). Остальные причины могут быть полностью устранены проверками во время компиляции. Итого мне известны всего 2 причины порчи памяти. Есть ли что-то еще?

А, ну да, в принципе еще бывает такая неприятность как кончилось место для стека...
Re[13]: Что толку в Ада если Ариан 5 все равно упал
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.07.05 14:22
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Здравствуйте, Cyberax, Вы писали:


>>> что еще-то???


C>>3) Гонки в MT

C>>4) Deadlock'и в MT
C>>5) Неосвобождение ресурсов
C>>6) Неправильная обработка исключений

СГ>Спасибо, но порчи памяти от этого не происходит.


Сергей, а ты многопоточностью-то точно занимался?

СГ>Порча памяти может произойти из-за неправильного индекса массива (1) и из-за неправильного преобразования/приведения типа (2).


3. Из-за того, что нить A начинает писать данные в разделяемую переменную, ее вытесняет нить B, которая пишет свои данные в туже самую переменную. Причина проблемы в том, что A и B не были правильно синхронизированны.

СГ> Остальные причины могут быть полностью устранены проверками во время компиляции. Итого мне известны всего 2 причины порчи памяти.


Кто-то из древних мудрецов сказал: "Я знаю, что ничего не знаю". Ведь он был прав, ты не находишь?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
LSP, ДК, Вирт - поехали...
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 06.07.05 14:34
Оценка:
Здравствуйте, Трурль, Вы писали:

ГВ>>Например, код, аналогичный вот такому анализу:


ГВ>>
ГВ>>    IF msg IS DrawMsg THEN (*draw rectangle r*)
ГВ>>    ELSIF msg IS MarkMsg THEN MarkRectangle(r, msg(MarkMsg).on)
ГВ>>    ELSIF msg IS MoveMsg THEN
ГВ>>


ГВ>>часто приводится в описаниях LSP как пример LSP-incompliancy.


Т>Думаю, не совсем аналогичный.

Т>
Т>IF msg IS DrawMsg THEN (* это выполняется для DrawMsg и всех его потомков*)
Т>


Однако, если сугубо формально, то анализ типа сообщения всё равно остаётся. Тем-то, кстати, и хорош LSP, что его нарушение можно определить по сугубо формальным признакам. Дизъюнктивная когерентность метода тоже присутствует (естественно!). Для справки, "дизъюнктивная когерентность", грубо говоря, это когда функция выполняет разные алгоритмы под влиянием значения входного параметра. Например, функция FormatMessage из Win32 — ни что иное, как ДК-функция из-за наличия параметра dwFlags, который определяет способы извлечения строк, способы форматирования и т.п.

Дальше в любом случае нужно анализировать саму задачу и её реализацию. В данный момент я оспариваю обобщение, сформулированное Сергеем Губановым:

AVC>>Еще иногда требуется проверка динамического типа переменной. Для этого в Обероне достаточно одного сравнения.
ГВ>А это вообще часто называется ошибкой проектирования.
Наоборот. Это такой способ проектирования.
http://www.inr.ac.ru/~info21/wirth/programming_in_oberon.pdf


Нет ничего удивительного в том, что для иллюстрации использования IS Вирт пользуется таким приёмом, в конце концов, иллюстрация есть иллюстрация. Никто же не заставляет, например, "в лоб" переносить объектные модели из книг Буча/Шлеера/и т.д. в реальные проекты (хотя некоторые горячие головы могут)!

Вроде бы и да, можно воспользоваться такой техникой в случае, если тег типа (имя типа) употребляется как переключатель. Но фактически, это почти то же самое, что и:


struct message {
  int type;
    // ...
};

#define DRAW_MESSAGE 12345
#define MARK_MESSAGE 67890
// ...

class Handler {

void handle(const message &msg)
{
  switch(msg.type)
    {
      case DRAW_MESSAGE: // ...
        case MARK_MESSAGE: // ...
    }
}

};


А такая техника обработки сообщений в общем-то, противоречит объектному стилю. Здесь причина зарыта достаточно глубоко и, ИМХО, начинается с того, что методы объектов сами по себе являются сообщениями, а внесение дублирующей структуры типа "сообщение" становится э... чем-то вроде тавтологии. Соответственно, нарушение фундаментального принципа тащит за собой нарушения и кучи других: архитектура смешивается, зависимости становятся неявными и т.п.

Так что, хотя такой "способ проектирования" и есть, но я бы не стал заявлять о нём, как о чём-то, имеющем ценность большую, чем сугубо иллюстративную.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[14]: Что толку в Ада если Ариан 5 все равно упал
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 06.07.05 14:40
Оценка:
Здравствуйте, eao197, Вы писали:

E>3. Из-за того, что нить A начинает писать данные в разделяемую переменную, ее вытесняет нить B, которая пишет свои данные в туже самую переменную. Причина проблемы в том, что A и B не были правильно синхронизированны.


Вы правы. Я об этом позабыл. Хорошо. Итого, теперь мы знаем три причины по которым можно испортить память:

1) неправильный индекс массива
2) неправильное приведение типа
3) неправильная синхронизация потоков, изменяющих одну и туже переменную

Две из них решаются с помощью проверок во время исполнения, от третьей, видимо, в принципе нет защиты, кроме аккуратного проектирования.

Есть ли еще?
Re[11]: Что толку в Ада если Ариан 5 все равно упал
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 06.07.05 14:44
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

ГВ>> ... этих "если" может быть вагон помимо индексов

СГ>Но почему вагон, ведь всего две (и обе уже решены):
СГ>1) Проверка индексов массивов;
СГ>2) Проверка правильности приведения/преобразования типов;
СГ>что еще-то???

Можно обобщить: любые проверки допустимости значений параметров. Между прочим, это немаловажная часть "программирования по контракту" — формулирование самого контракта в явном, машиночитаемом виде.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[24]: Что толку в Ада если Ариан 5 все равно упал
От: Кодт Россия  
Дата: 06.07.05 14:49
Оценка: +1
Здравствуйте, CrystaX, Вы писали:

CX>>>Но у меня есть определение термину "compile-time метапрограммирование". Это возможность с помощью определенных языковых конструкций изменять поведение компилятора. Подчеркиваю — изменять поведение компилятора, а не конечной программы!

Т>>А использование прагм — это "compile-time метапрограммирование"?
CX>Нет. Так как а) они не являются языковыми конструкциями и б) жестко задают поведение компилятора без возможности выбора.

Э! Любая программа, поданная на вход компилятора, "меняет" его поведение, потому что "обычное" поведение компилятора — в основном это лежать на диске и никого не трогать

Прагмы как раз влияют на компилятор, в бОльшей степени, чем compile-time программирование.

Compile-time означает, что некоторую часть действий компилятор берёт на себя:
— парсинг (по сравнению со скриптовыми языками)
— порождение объектного кода (по сравнению с интерпретаторами)
— вычисление констант (некоторые дубовые компиляторы вполне могут родить код, перевычисляющий 2*2 каждый раз)
— сопоставление типов (нетипизированные языки откладывают это на время исполнения)
— воплощение шаблонов (альтернатива — нетипизированные конструкции и сопоставление в рантайме)
Всё это поведение является штатным, разной степени затейливости.
Перекуём баги на фичи!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.