web-dev-qa-db-fra.com

C est-il fortement typé?

Pour citer Wikipedia :

C et C++ sont deux langages couramment utilisés qui prennent en charge de nombreux types de conversion implicite, et il est parfois affirmé que ce sont des langages faiblement typés. Cependant, d'autres soutiennent que ces langues imposent suffisamment de restrictions sur la façon dont les opérandes de différents types peuvent être mélangés, que les deux doivent être considérés comme des langues fortement typées.

Y a-t-il une réponse plus définitive?

75
Sydius

"Fortement typé" et "faiblement typé" sont des termes qui n'ont pas de signification technique largement acceptée. Les termes qui ont une signification bien définie sont

  • Typé dynamiquement signifie que les types sont attachés à des valeurs au moment de l'exécution, et une tentative de mélanger des valeurs de différents types peut provoquer une "erreur de type au moment de l'exécution" . Par exemple, si dans Scheme vous essayez d'en ajouter un à true en écrivant (+ 1 #t) cela provoquera une erreur. Vous rencontrez l'erreur uniquement si vous essayez d'exécuter le code incriminé.

  • Typé statiquement signifie que les types sont vérifiés au moment de la compilation et qu'un programme qui n'a pas de type statique est rejeté par le compilateur. Par exemple, si en ML vous essayez d'en ajouter un à true en écrivant 1 + true, le programme sera rejeté avec un message d'erreur (probablement cryptique). Vous obtenez toujours l'erreur même si le code risque de ne jamais être exécuté.

Différentes personnes préfèrent des systèmes différents en fonction en partie de la valeur qu’elles accordent à la flexibilité et de leur inquiétude concernant les erreurs d’exécution.

Parfois, "fortement typé" est utilisé de manière lâche pour signifier "typiquement" et "faiblement typé" est incorrectement utilisé pour signifier "typé dynamiquement". Une meilleure utilisation du terme "fortement typé" est que "vous ne pouvez pas contourner ou renverser le système de type", tandis que "faiblement typé" signifie "il y a des failles dans le système de type". Perversement, la plupart des langues avec des systèmes de type statiques ont des failles, tandis que de nombreuses langues avec des systèmes de type dynamiques n'ont pas de failles.

Aucun de ces termes n'est lié de quelque manière que ce soit au nombre de conversions implicites disponibles dans une langue.

Si vous voulez parler précisément des langages de programmation, il vaut mieux éviter les termes "fortement typé" et "faiblement typé". Je dirais que C est un langage typé statiquement mais qui a beaucoup d'échappatoires. Une faille est que vous pouvez librement convertir n'importe quel type de pointeur en n'importe quel autre type de pointeur. Vous pouvez également créer une échappatoire entre deux types de votre choix en déclarant une union C qui a deux membres, un pour chacun des types en question.

J'ai écrit plus sur la frappe statique et dynamique sur pourquoi-les-langs-interprétés-sont-principalement-ducktypés-alors-compilés-ont-une-frappe forte .

141
Norman Ramsey

Il est difficile de classer chaque langue en caractères "faiblement" ou "fortement" - il s'agit plutôt d'un continuum. Mais, par rapport à d'autres langages, C est assez fortement typé. Chaque objet a un type au moment de la compilation, et le compilateur vous fera savoir (fort) si vous faites quelque chose avec un objet que son type ne vous permet pas de faire. Par exemple, vous ne pouvez pas appeler des fonctions avec les mauvais types de paramètres, accéder aux membres struct/union qui n'existent pas, etc.

Mais il y a quelques faiblesses. Une des principales faiblesses est les typecasts - ils disent essentiellement que vous allez fouiner avec les types d'objets, et le compilateur doit être silencieux (quand il le peut). void* est également une autre faiblesse - c'est un pointeur générique vers un type inconnu, et lorsque vous les utilisez, vous devez faire très attention à ce que vous fassiez la bonne chose. Le compilateur ne peut pas vérifier statiquement la plupart des utilisations de void*. void* peut également être converti en pointeur vers n'importe quel type sans transtypage (uniquement en C, pas en C++), ce qui est une autre faiblesse.

21
Adam Rosenfield

C est considéré comme faiblement typé, car vous pouvez convertir n'importe quel type en n'importe quel autre type via un transtypage, sans erreur de compilation. Vous pouvez en savoir plus sur le problème ici .

11
mipadi

La littérature n'est pas claire à ce sujet. Je pense que fortement tapé n'est pas oui/non, il existe différents degrés de frappe forte.

Un langage de programmation a une spécification de la façon dont il exécute les programmes. Parfois, il n'est pas clair comment exécuter avec certains programmes. Par exemple, les programmes qui tentent de soustraire une chaîne d'un nombre. Ou des programmes qui divisent par zéro. Il existe plusieurs façons de faire face à ces conditions. Certaines langues ont des règles pour gérer ces erreurs (par exemple, elles lèvent une exception). D'autres langues n'ont tout simplement pas de règles pour faire face à ces situations. Ces langages ont généralement des systèmes de types pour empêcher la compilation de programmes qui conduisent à un comportement non spécifié. Et il existe également des langages qui ont un comportement non spécifié et n'ont pas de système de type pour empêcher ces erreurs au moment de la compilation (si vous écrivez un programme qui atteint un comportement non spécifié, il pourrait lancer les missiles).

Donc:

Les langages qui spécifient ce qui se passe au moment de l'exécution dans tous les cas (comme l'ajout d'un nombre à une chaîne) sont appelés typés dynamiquement. Les langages qui empêchent l'exécution de programmes avec des erreurs au moment de la compilation sont typés statiquement. Les langages qui ne spécifient pas ce qui se passe et qui n'ont pas non plus de système de saisie pour éviter les erreurs sont appelés faiblement typés.

Est donc Java typé statiquement? Oui, parce que son système de type interdit la soustraction d'une chaîne d'un nombre. Non, car il vous permet de diviser par zéro. Vous pouvez empêcher la division par zéro lors de la compilation avec un système de types. Par exemple, en créant un type de nombre qui ne peut pas être nul (par exemple NonZeroInt), et en autorisant uniquement la division par des nombres qui ont ce type.

Le C est-il donc fortement typé ou faiblement typé? C est fortement typé car le système de type interdit certaines erreurs de type. Mais il est faiblement tapé dans d'autres cas lorsqu'il n'est pas défini ce qui se passe (et le système de type ne vous protège pas).

9
Jules

C est plus fortement typé que Javascript et moins fortement typé que Ada.

Je dirais que cela tombe davantage dans le côté fortement typé du continuum. mais quelqu'un d'autre pourrait être en désaccord (même s'il a tort).

Comment est-ce définitif?

7
Michael Burr

Beaucoup de bonnes réponses ici. Je veux soulever un point important de Real World Haskell :

Il est utile de savoir que de nombreuses communautés linguistiques ont leurs propres définitions d'un "type fort". Néanmoins, nous parlerons brièvement et en termes généraux de la notion de force dans les systèmes de types.

(couper)

Les feux d'artifice autour des systèmes de types ont leurs racines dans un anglais ordinaire, où les gens attachent des notions de valeur aux mots "faible" et "fort": nous pensons généralement que la force est meilleure que la faiblesse. Beaucoup plus de programmeurs parlent un anglais simple que le jargon universitaire, et bien souvent, les universitaires lancent des briques sur le système de type qui ne leur convient pas. Le résultat est souvent ce passe-temps Internet populaire, une guerre des flammes.

Alors, regardez les réponses sur C et C++, mais rappelez-vous que "fort" et "faible" ne correspondent pas à "bon" et "mauvais".

4
slim

C est considéré comme typé statiquement (vous ne pouvez pas faire passer une variable de int à float). Une fois qu'une variable est déclarée, elle est bloquée de cette façon.

Mais il est considéré comme faiblement typé car les types peuvent être retournés.

Qu'est-ce que 0? '\ 0', FAUX, 0,0, etc.

dans de nombreuses langues, vous ne pouvez pas dire IF (variable) car les conditions ne prendront que des valeurs booléennes à partir d'expressions booléennes. Ceux-ci sont plus fortement typés. Il en va de même pour passer d'un caractère à un autre.

fondamentalement, c a deux principaux types de données simples, des entiers et des nombres à virgule flottante (bien que diverses précisions). Tout le reste, les booléens, les énumérations (pas simple mais cela convient), etc. sont implémentés comme l'un d'eux. Même les caractères sont essentiellement des entiers.

Comparez avec d'autres langages où il existe des types de chaîne, des types d'énumération qui ne peuvent être affectés qu'aux valeurs définies, des types booléens où seules les expressions qui génèrent des booléens ou true/false peuvent être utilisées.

Mais vous pouvez affirmer que, comparé à Perl, C est fortement typé. C'est donc l'un de ces fameux arguments (vi vs emacs, linux vs windows, etc.). C # est plus typé que C. En gros, vous pouvez argumenter dans les deux sens. Et vos réponses iront probablement dans les deux sens :) De plus, certains manuels/pages Web diront que C est faiblement tapé, et certains diront que C est fortement tapé. Si vous allez sur wikipedia, l'entrée C indique "typage partiellement faible". Je dirais par rapport à Python C est faiblement typé. Donc Python/C #, C, Perl sur le continuum.

4
Cervo

Le terme fortement tapé n'a pas de définition convenue. Par conséquent, à moins que vous ne définissiez ce que vous voulez dire par "fortement tapé", il est impossible de répondre à votre question.

D'après mon expérience, les termes "fortement typés" et "faiblement typés" sont utilisés exclusivement par les trolls, car leur manque de définitions permet aux trolls de les redéfinir mi-argument pour convenir à leur ordre du jour. Autre que pour déclencher des guerres de flammes, ces termes sont à peu près inutiles.

Vous pouvez également jeter un œil à Quels sont les aspects clés d'un langage fortement typé? ici sur StackOverflow.

2
Jörg W Mittag

Selon Dennis Ritchie (créateur de C) et Brian Kernighan, C n'est pas un langage fortement typé. Les lignes suivantes sont extraites du livre Le langage de programmation C page 3 paragraphe 5

C n'est pas un langage fortement typé, mais comme il a évolué, sa vérification de type a été renforcée.

2
mightyWOZ

À mon avis, C/C++ sont fortement typés. Le type de hacks qui permettent de convertir les types (void *) existe en raison de la proximité de C avec la machine. En d'autres termes, vous pouvez appeler des commandes d'assembleur depuis Pascal et manipuler des pointeurs et Pascal est toujours considéré comme un langage fortement typé. Vous pouvez appeler l'assembleur et les exécutables C depuis Java via JNI mais cela ne fait pas Java faiblement typé.

C a juste assembleur "incorporé" avec des pointeurs bruts et autres.

2
mannicken

Il existe un continuum avec de multiples voies parallèles entre "faiblement typé" et "fortement typé", deux termes qui ne sont même pas bien définis.

C est statiquement typé, en ce que le compilateur sait quel est le type déclaré de chaque variable locale et membre struct.

Les langages typés dynamiquement peuvent toujours être fortement typés, si chaque objet a un type spécifique mais qu'il n'y a aucun moyen pour le compilateur de connaître ce type.

1
yfeldblum

c est faiblement typé, b est sans type.

1
plan9assembler

Je dirais que C est aussi fortement typé que le veut votre compilateur/plateforme. Par exemple, si vous construisez sur une plateforme stricte, le déréférencement d'un pointeur punned de type va probablement se casser:

void m_free(void **p)
{
        if (*p != NULL) {
                free(*p);
                *p = NULL;
        }
}

....
char *str = strdup("foo");
m_free((void **) &foo);

Maintenant, si vous demandiez au compilateur d'ignorer l'alias strict, ce ne serait pas un problème, mais pas très portable. Donc, dans ce sens, repousser les limites de la langue est possible mais probablement pas la meilleure idée. Cela va au-delà du casting typique, c'est-à-dire que le casting est aussi long et montre vraiment l'un des pièges possibles du vide.

Donc, je dirais que C est typiquement strictement typé, mais ses différents compilateurs supposent que le programmeur connaît le mieux et permet une certaine flexibilité. Cela dépend vraiment du compilateur, certains ne capteraient pas ce potentiel. Donc, dans ce sens, le compilateur de choix joue vraiment un rôle lors de la réponse à la question. Ce qui est correct diffère souvent de ce que votre compilateur vous permettra de faire.

0
Tim Post

Quelle est la raison de votre requête? La raison pour laquelle je pose cette question est une sorte de différence mineure et votre utilisation particulière de "fortement typé" pourrait nécessiter plus ou moins de clarification. Je dirais certainement que Java et d'autres langages ont des restrictions plus strictes sur la conversation de type implicite.

0
BobbyShaftoe

Il est difficile de fournir une réponse concrète lorsqu'il n'existe pas de définition concrète de "fortement typé". Je dirais que C est fortement typé en ce que chaque variable et chaque expression a un type mais faiblement typé en ce qu'il vous permet de changer de type à l'aide de transtypages et de réinterpréter la représentation d'un type comme d'un autre.

0
Robert Gamble