[uquote="ARV",url="/forum/viewtopic.php?p=3819859#p3819859"]Чем меньше преобразования типов по умолчанию (неявных) допускает язык, тем строже типизация языка.
Такое определение вас устроит?[/uquote]
Это - прекрасное определение. Я ничего не имею против него.
[uquote="ARV",url="/forum/viewtopic.php?p=3819859#p3819859"]Вроде как во всем мире именно его используют, когда говорят об этом. Почему вам это не известно, хотя вы беретесь об этом говорить, я не понимаю.[/uquote]
Дискуссии о том, что считать строгой типизацией, а что нет, обычно фокусируются на различиях между "object context" (типизация представления объекта в памяти) и "value context" (типизация абстрактного значения, без привязки к памяти).
Я придерживаюсь мнения о том, что понятие строгой типизации стоит применять только к объектным контекстам. То есть строгая типизация - это когда язык не позволяет вам производить доступ к представлению в памяти объекта типа `T`, как к объекту типа `U`. В терминах С и/или С++ строгая типизация - это запрет на неявное преобразование указателей типа `T *` и `U *` друг к другу (или ссылок `T &` и `U &` друг к другу) с целью последующей "переинтерпретации" указуемой памяти. Языки С и С++ на декларативном уровне запрещают такое использование (т.наз. правила strict aliasing), а также принимают ряд меры для того, чтобы заставить вас использовать
явные преобразования в таких ситуациях, если вам вдруг приспичит эти преобразования выполнить. Эти меры имеют кое-какие обходные "дыры", но и их использование требует более-менее явных усилий.
Вот это я считаю строгой типизацией.
А нарушения типизации в "value context", т.е. возможность неявно преобразовать `short` к `int` и даже `int` к `unsigned int` и `double` к `int` я нарушениями строгой типизации не считаю. Тем не менее, современный С++ сделал шаги к затягиванию гаек в этом направлении (см. narrowing conversions).
---
[uquote="ARV",url="/forum/viewtopic.php?p=3819859#p3819859"]Варнинг (это уже не про типизацию) это сообщение компилятора о месте в коде, где имеется допускаемое синтаксисом языка действие, которое может иметь побочные эффекты.
Ошибка - это недопускаемое синтаксисом языка действие.
Тут тоже определения вроде как общепринятые, и с чего вы стали их по-своему интерпретировать, тоже вопрос интересный...[/uquote]
Нет, нет, нет... Вы в общем и целом близки к истине, но все таки определения дали очень и очень неточные! Как вы сами правильно заметили, существуют
общепринятые определения. Давайте их уточним.
Общепринятым определением понятия "ошибка" в языке С называется то, что описывается в разделе
5.1.1.3 стандарта языка С. А именно: нарушение синтаксиса и нарушения ограничений (constraints). Вот эту вторую часть - нарушения ограничений - вы потеряли. В результате у вас получилось неправильное определение "ошибки", ничего общего не имеющее с общепринятым.
Проиллюстрирую примером:
Это код не содержит нарушений синтаксиса языка С. Однако он грубейше ошибочен. Он содержит нарушение constraint
6.4.8.2/1, которое говорит, что значение в `switch` обязано быть целочисленным.
Еще один пример:
Это код не содержит нарушений синтаксиса языка С. Однако он ошибочен. Он содержит нарушение constraint
6.8.6.1/1, которое говорит, что `goto` должно ссылаться на метку, располагающуюся в той же функции.
Еще один пример:
Это код не содержит нарушений синтаксиса языка С. Однако он ошибочен. Он содержит нарушение constraint
6.5.3.1/1, которое говорит, что операнд унарного `++` должен быть
модифицируемым lvalue.
Да и в стандарте по
ссылке приведен пример
Это код не содержит нарушений синтаксиса языка С. Ну вы поняли...
Теперь, надеюсь, вам понятно, что ваше "ошибка - это недопускаемое синтаксисом языка действие" - это не более чем детский лепет?
Давайте теперь составим настоящие, серьезные определения
общепринятых понятий "ошибка" и "варнинг":
"Ошибка" - это нарушение синтаксиса языка или нарушение ограничений (constraints) языка. Язык С требует, чтобы при возникновении "ошибки" компиляторы выдавали диагностическое сообщение. Язык С не накладывает никаких требований на формат этого диагностического сообщения (не требуется наличия в нем слова "error"). Язык С не требует прекращения трансляции поле выдачи такого сообщения.
"Варнинг" - это все остальное. Это когда компилятор решил проинформировать пользователя о каких-то странностях в коде, для которых стандарт языка НЕ требует выдачи диагностического сообщения. Например, нарушение
семантических правил языка. Или, например, код, вызывающий неопределенное поведение. Такие ситуации формально не требуют никакой диагностики со стороны компилятора. Однако продвинутый компилятор имеет право обнаруживать такие отклонения и сообщать о них дополнительными диагностическими сообщениями. Как и имеет право сообщать вообще о чем угодно.
Вот это то, что
общепринято называется "ошибками" и "варнингами".
---
А теперь, когда мы ввели правильные определения, я еще раз повторю тот ключевой момент, который я уже приводил выше:
Среди малоопытных пользователей языка С существует наивное верование, что вышеприведенное деление на "ошибки" и "варнинги" совпадает с делением на сообщения вида "error: ..." (с прекращением трансляции) и "warning: ..." (без прекращения трансляции) в современных мейнстримовых компиляторах С. Это не так. Практически все мейнстримовые компиляторы С в конфигурации по умолчанию рапортуют некоторые "ошибки" через сообщения типа "warning: ...". Это зачастую приводит к тому, что малоопытные пользователи неверно полагают, что перед ними "варнинг", когда на самом деле пред ними "ошибка", отрапортованная со словом "warning".
Например
Перед вами грубое нарушение constraints
6.5.16.1/1, то есть то, что общепринято называется "ошибкой". Однако компилятор GCC в конфигурации по умолчанию отреагирует на этот код сообщением со словом "warning...".
То есть некоторые сообщения "warning..." являются "варнингами", а некоторые сообщения "warning..." являются "ошибками" с точки зрения языка С.
Как вы сами понимаете (и как я говорил выше) в такой ситуации отличить первые от вторых можно
1) на основе знания стандарта языка С, или
2) путем "затягивания гаек" в настройках компилятора, чтобы заставить компилятор рапортовать "ошибки" как "error...".
Но малоопытные пользователи языка С, как правило, не умеют ни того, ни другого. В результате рождаются мифы об "отсутствии контроля типов в С" и прочая подобная чушь.