2014-11-05 5 views
6

Я всегда считал, что C++ является одним из наиболее строго типизированных языков.
Так что я был довольно потрясен, чтобы увидеть Table 3 of this paper, что C++ слабо типизирован.Рассматривается ли С ++ слабо типизированным? Зачем?

По-видимому,

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

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

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

+1

Если вы когда-либо программировали в Haskell, вы узнаете, как C++ действительно слабо типизирован! ;-) – Claudix

+2

C++ не слабо типизирован, но вы можете подорвать систему типов, если хотите. Поэтому можно утверждать, что он не полностью строго типизирован. – juanchopanza

+0

.. и если он позволяет вам (тип punning сложный) –

ответ

16

, что бумага первой претензии:

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

А потом утверждает:

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

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

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

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

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

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

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

+0

+1 отличный момент.Но чтобы ответить на вопрос, вы должны также упомянуть, действительно ли C++ строго типизирован любым принятым определением! – Mehrdad

+1

+1 хороший улов против противоречия! –

+1

@Mehrdad Согласился и расширил мой ответ. – hvd

5

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

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

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

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

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

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

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

0

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

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

#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 и C++ считаются слабо типизированных, так как из-за типа литья, можно интерпретировать поле структура, которая была целым числом как указатель.

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

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

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

В целом, общепризнано, что C++ слабо типизирован? Зачем?

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

-2

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

if (a + b) 

C/C + = допускает неявное преобразование из поплавка Int в логическое значение.

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

 Смежные вопросы

  • Нет связанных вопросов^_^