C++ считается слабо типизированным? Зачем?

Я всегда считал, что С++ является одним из наиболее строго типизированных языков. Поэтому я был очень шокирован тем, что Таблица 3 этой статьи утверждает, что С++ слабо типизирован.

Очевидно,

C и С++ считаются слабо типизированными, поскольку из-за литья типов можно интерпретировать поле структуры, которое было целым числом в качестве указателя.

Является ли существование различного типа литьем все, что имеет значение? Является ли явная ясность таких отбросов неважно?

В целом, действительно ли общепризнано, что С++ слабо типизирован? Почему?

Ответ 1

В этой статье сначала говорится:

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

И затем утверждает:

Кроме того, C и С++ считаются слабо типизированными, поскольку из-за литья типов можно интерпретировать поле структуры, которое было целым числом в качестве указателя.

Это кажется мне противоречием. В C и С++ путаница типа, которая может возникнуть в результате приведения, не будет происходить беззвучно - там есть бросок! Это не показывает, что любой из этих языков слабо типизирован, по крайней мере, не по определению в этой статье.

Тем самым, по определению в документе, C и С++ все еще можно считать слабо типизированным. Как уже отмечалось в комментариях по этому вопросу, случаи, когда язык поддерживает неявные преобразования типов. Многие типы могут быть неявно преобразованы в bool, буквальный нуль типа int может быть безшовно преобразован в любой тип указателя, есть преобразования между целыми числами разного размера и т.д., Поэтому это кажется веской причиной для рассмотрения C и С++ слабо типизирован для целей статьи.

Для C (но не С++) есть также более опасные неявные преобразования, которые стоит упомянуть:

int main() {
  int i = 0;
  void *v = &i;
  char *c = v;
  return *c;
}

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

В общем, однако, я думаю, что не существует фиксированного определения "сильно типизированного" и "слабо типизированного". Существуют различные классы, язык, который строго типизирован по сравнению с сборкой, может быть слабо типизирован по сравнению с Pascal. Чтобы определить, является ли C или С++ слабо типизированным, сначала вам нужно спросить, что вы хотите, чтобы слабо типизировалось.

Ответ 2

"слабо типизированный" - довольно субъективный термин. Я предпочитаю термины "строго типизированные" и "статически типизированные" против "слабо типизированные" и "динамически типизированные",, потому что они более объективные и более точные слова.

Из того, что я могу сказать, люди обычно используют "слабо типизированный" как уменьшительно-уничижительный термин, что означает "мне не нравится понятие типов на этом языке". Это своего рода аргумент ad hominem (вернее, argumentum ad linguam) для тех, кто не может воспитывать профессиональные или технические аргументы против определенного языка.

Термин "строго типизированный" также имеет несколько разные интерпретации; общепринятое значение, по моему опыту, заключается в том, что "компилятор генерирует ошибки, если типы не совпадают". Другая интерпретация заключается в том, что "нет или несколько неявных преобразований". Основываясь на этом, С++ действительно может считаться строго типизированным языком, и чаще всего он считается таковым. Я бы сказал, что общий консенсус по С++ заключается в том, что он строго типизированный язык.

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

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

В действительности части С++ (виртуальные вызовы) налагают требование, чтобы система типов была частично динамичной, но другие вещи в стандарте требуют, чтобы она была строгой. Опять же, это не проблема, так как это ортогональные понятия.

Подводя итог: вероятно, язык не подходит полностью, совершенно в одну категорию или другую, но мы можем сказать, какое особое свойство данного языка доминирует. В С++ строго определенность строго доминирует.

Ответ 3

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

Ну, это может произойти в С++, например:

#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <limits>

void f(char n) { std::cout << "f(char)\n"; }
void f(int n) { std::cout << "f(int)\n"; }
void g(int n) { std::cout << "f(int)\n"; }

int main()
{
    float fl = M_PI;   // silent conversion to float may lose precision

    f(8 + '0'); // potentially unintended treatment as int

    unsigned n = std::numeric_limits<unsigned>::max();
    g(n);  // potentially unintended treatment as int
}

Кроме того, C и С++ считаются слабо типизированными, поскольку из-за литья типов можно интерпретировать поле структуры, которое было целым числом в качестве указателя.

Ummmm... не через какое-либо неявное преобразование, так что глупый аргумент. С++ допускает явное литье между типами, но это вряд ли "слабое" - это не случается случайно/тихо, как того требует определение собственного сайта выше.

Является ли существование различного типа литьем все, что имеет значение? Является ли явная необходимость таких отбросов неважной?

Объяснение является важным соображением ИМХО. Предоставление программисту переопределения знаний о типах компиляторов является одной из "мощных" возможностей С++, а не некоторой слабости. Он не подвержен случайному использованию.

В целом, действительно ли общепризнано, что С++ слабо типизирован? Почему?

Нет - я не думаю, что это принято. С++ достаточно строго типизирован, а способы, в которых он был снисходителен, которые исторически вызвали проблемы, были отброшены назад, такие как неявные отбрасывания от void* к другим типам указателей и более тонкое управление с помощью операторов explicit и операторов-конструкторов.

Ответ 4

Итак, поскольку создатель C++ Бьярн Страуструп в "Языке программирования C++" (4-е издание) говорит, что язык строго типизирован, я бы взял его слово:

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

В этой видео-лекции 1994 года он также заявляет, что слабая система типов Си действительно беспокоила его, и поэтому он сделал C++ строго напечатанным: Дизайн C++, лекция Бьярна Страуструпа

Ответ 5

Позвольте мне привести простой пример:

 if ( a + b )

C/C + = позволяет неявное преобразование из float в int в Boolean.

Сильно типизированный язык не допускает такого неявного преобразования.