Le C est-il fortement typé?

87

Pour citer Wikipedia :

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

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

Sydius
la source
188
Pour un programmeur C, taper fort signifie appuyer plus fort sur les touches.
Dan Dyer
2
C est sur le côté faible dans le continuum de typage. Mais il y a suffisamment d'éléments de chaque côté que vous pouvez discuter de toute façon. Pendant que vous y êtes, vous pouvez aussi bien demander (vi ou emacs, netbeans ou éclipse, etc.)
Cervo
4
L'état d'avancement de Wikipédia était suffisamment mauvais pour que je me sente obligé de modifier plusieurs pages de Wikipédia. Peut-être que les choses vont un peu mieux maintenant. Peut être.
Norman Ramsey
40
Re: Le commentaire de Dan (pour donner le crédit là où il est dû) Le livre de Peter van der Linden "Expert C Programming" contient la ligne suivante: "À ce jour, de nombreux programmeurs C croient que 'taper fort signifie simplement taper très fort sur le clavier."
Alexandros Gezerlis
Très bonne question !!!
Destructor

Réponses:

154

«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

  • Dynamiquement typé signifie que les types sont attachés aux valeurs au moment de l'exécution, et une tentative de mélanger des valeurs de types différents peut provoquer une "erreur de type d'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é.

  • Statiquement typé signifie que les types sont vérifiés au moment de la compilation et un programme qui n'a pas de type statique est rejeté par le compilateur. Par exemple, si dans 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 pourrait ne jamais être exécuté.

Différentes personnes préfèrent des systèmes différents selon en partie à quel point ils apprécient la flexibilité et à quel point ils s'inquiètent des erreurs d'exécution.

Parfois, «fortement typé» est utilisé vaguement pour signifier «typé statiquement», et «faiblement typé» est utilisé à tort pour signifier «typé dynamiquement». Une meilleure utilisation du terme «fortement typé» est que «vous ne pouvez pas contourner ou renverser le système de typage», alors que «faiblement typé» signifie «il y a des failles dans le système de typage». De manière perverse, la plupart des langages avec des systèmes de types statiques ont des failles, tandis que de nombreux langages avec des systèmes de types dynamiques n'ont pas de failles.

Aucun de ces termes n'est lié en aucune façon 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 présente de nombreuses failles. Une faille est que vous pouvez convertir librement n'importe quel type de pointeur en tout autre type de pointeur. Vous pouvez également créer une faille entre deux types quelconques 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 le typage statique et dynamique à pourquoi-interprétés-langs-sont-principalement-ducktyped-while-compiled-have-strong-typing .

Norman Ramsey
la source
2
D'où avez-vous trouvé les définitions que vous suggérez pour le typage fort / faible (la faille)?
Sydius
2
Pourquoi auriez-vous besoin d'une «faille» dans un environnement de frappe dynamique?
Chris Conway
4
@Sydius: Après avoir passé une grande partie des 20 dernières années à traîner avec des personnes qui conçoivent, construisent et analysent des langages de programmation et des systèmes de typage. C'est mon travail rémunéré :-)
Norman Ramsey
@Chris: Je n'ai jamais vu un langage typé dynamiquement avec 'échappatoire'. L'utilisation courante de la faille est de travailler avec un système d'exécution ou un système d'exploitation, par exemple, prendre une adresse brute et la convertir en un pointeur en une valeur de langage bien comportée. Vous pouvez le faire dans un cadre dynamique mais je ne connais aucune tentative.
Norman Ramsey
1
@NormanRamsey Je pense que Chris faisait référence avec sa question à:whereas "weakly typed" means "there are loopholes in the type system
Nir Alfasi
23

Il est difficile de classer chaque langue en caractères «faiblement» ou «fortement» - il s'agit plutôt d'un continuum. Mais, en comparaison avec 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 laisse pas faire. Par exemple, vous ne pouvez pas appeler des fonctions avec les mauvais types de paramètres, accéder aux membres de structure / union qui n'existent pas, etc.

Mais il y a quelques faiblesses. Une faiblesse majeure est les typecasts - ils disent essentiellement que vous allez vous débrouiller 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 à faire la bonne chose. Le compilateur ne peut pas vérifier statiquement la plupart des utilisations de void*. void*peut également être converti en un pointeur vers n'importe quel type sans conversion (uniquement en C, pas en C ++), ce qui est une autre faiblesse.

Adam Rosenfield
la source
Bonne réponse, même si "les typecasts ... et le compilateur devrait être silencieux" me dérange. Un transtypage n'est pas comme arrêter un avertissement, il change en fait l'interprétation de la valeur référencée.
Tall Jeff
15
Vous confondez «statique» et «fort» par rapport à la frappe. Ces deux concepts sont indépendants l'un de l'autre.
bendin
1
Dennis Richie (auteur C) a appelé C `` fortement typé et faiblement vérifié ''
TimZaman
11

La littérature n'est pas claire à ce sujet. Je pense que le typage fort n'est pas oui / non, il existe différents degrés de typage fort.

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 se divisent par zéro. Il existe plusieurs façons de gérer ces conditions. Certaines langues ont des règles pour traiter ces erreurs (par exemple, elles lancent une exception). D'autres langues n'ont tout simplement pas de règles pour gérer 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 qui n'ont pas de système de type pour éviter ces erreurs au moment de la compilation (si vous écrivez un programme qui rencontre un comportement non spécifié, il peut lancer les missiles).

Donc:

Les langages qui spécifient ce qui se passe à l'exécution dans tous les cas (comme l'ajout d'un nombre à une chaîne) sont appelés dynamiquement typés. 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 type pour éviter les erreurs sont appelés faiblement typés.

Alors Java est-il typé statiquement? Oui, car son système de type interdit de soustraire une chaîne à un nombre. Non, car cela vous permet de diviser par zéro. Vous pouvez empêcher la division par zéro au moment de la compilation avec un système de types. Par exemple en créant un type de nombre qui ne peut pas être zéro (par exemple NonZeroInt), et ne permet de diviser que par des nombres de ce type.

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

Jules
la source
J'aime votre alignement du dynamique et du statique en tant que formes de fort et de faible. Cependant, je ne suis pas sûr de comprendre votre point de vue sur les systèmes statiquement typés arrêtant la division par zéro. Si mon typé statiquement intobtient une valeur de l'utilisateur, des arguments de ligne de commande ou d'un fichier, le compilateur ne peut rien faire pour empêcher que ce soit un zéro!
Rikki
1
Il existe des systèmes de types statiques qui empêchent cela, mais la plupart des langages sont soit faiblement ou dynamiquement «typés» par rapport à la division par zéro, parce que c'est un comportement non défini (C) ou qu'ils lancent une exception (Java).
Jules
11

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

mipadi
la source
2
wikipedia est trompeur ici. C est fortement typé, les types sont très valides et le compilateur barf si vous vous trompez, cependant, C fournit également des fonctionnalités pour vous permettre de contourner cela. Comparez avec des langages comme BCPL qui n'ont qu'un type «octet».
gbjbaanb
12
Faiblement typé ne signifie pas qu'un langage n'a aucun type, cela signifie simplement que les types peuvent être implicitement forcés d'un type à un autre. Comparez à Python, un langage fortement typé dans lequel vous devez explicitement convertir des types avec des appels de fonction.
mipadi
est-ce que la capacité de lancer une chose en C contribue également à ce que ce soit un type faible. ?? J'ai ce doute pour toujours
Suraj Jain
8

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

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

Comment est-ce définitif?

Michael Burr
la source
C'était une réponse quelque peu ironique. Mais élaborez sur le mal.
Michael Burr
1
Javascript est fortement typé. Il n'est tout simplement pas typé statiquement. Toutes les vérifications de type se produisent au moment de l'exécution (dynamique, pas statique), mais elles se produisent et vous empêchent de corrompre la mémoire (un aspect du typage fort).
bendin le
5
Eh bien, comme l'indique la très bonne réponse de Norm Ramsey, «fortement typé» et «faiblement typé» ne sont pas des termes particulièrement bien définis. Aussi, dans la mesure où Javascript est fortement typé, certains pourraient penser que ("4" / ​​"2") étant une expression Javascript valide, cela pourrait indiquer le contraire.
Michael Burr
5

C est considéré comme statiquement typé (vous ne pouvez pas changer de 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 inversés.

Qu'est-ce que 0? '\ 0', FALSE, 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. La même chose s'applique au passage entre les caractères et les entiers.

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 des booléens, des énumérations (pas simples mais qui correspondent), etc. sont implémentés comme l'un de ceux-ci. Même les caractères sont essentiellement des entiers.

Comparez avec d'autres langages où il existe des types chaîne, des types enum 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 vrai / faux peuvent être utilisées.

Mais vous pouvez affirmer que par rapport à 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 cas. Et vos réponses iront probablement dans les deux sens :) De plus, certains manuels / pages Web indiqueront que C est faiblement typé, et certains diront que C est fortement typé. Si vous allez sur wikipedia, l'entrée C dit "typage partiellement faible". Je dirais que par rapport à Python C est faiblement typé. Donc Python / C #, C, Perl sur le continuum.

Cervo
la source
Veuillez expliquer votre raisonnement selon lequel Perl est moins fortement typé que C.
user51568
print "Test" + 0 # perl fera 0; $ var = "chaîne"; $ var = 1; $ var = 123,4; De quel genre de variable s'agit-il?
Cervo
En C char * test = "testing"; printf (test + 0); sera toujours une chaîne, c'est juste que dans C l'index changera si au lieu de zéro j'utilise un nombre. C'est encore assez faible, mais un peu plus fort que perl. char * test; test = 0; test = 123,4; test = "c"; ... mon compilateur génère des erreurs
Cervo
l'erreur indique qu'une distribution est requise. Pourtant, il est un peu plus fort d'un contrôle de type que Perl, donc sur le continuum, je dois dire que C est plus fortement typé que Perl. Vous pouvez toujours aller tester = (char *) puis utiliser 0, 123.4, 'C', etc. Mais c'est une erreur de le faire.
Cervo
4

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 du «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 caractères ont leurs racines dans l'anglais ordinaire, où les gens attachent des notions de valeur aux mots «faible» et «fort»: nous pensons généralement que la force vaut mieux que la faiblesse. Beaucoup plus de programmeurs parlent un anglais simple que le jargon académique, et très souvent, les universitaires lancent vraiment des brioches sur tout type de système 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».

svelte
la source
4

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

C n'est pas un langage fortement typé, mais au fur et à mesure de son évolution, sa vérification de type a été renforcée.

puissantWOZ
la source
3

A mon avis, C / C ++ sont fortement typés. Les types de hacks qui permettent de convertir les types (void *) sont là en raison de la proximité de C avec la machine. En d'autres termes, vous pouvez appeler des commandes assembleur à partir de 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 de Java via JNI, mais cela ne rend pas Java faiblement typé.

C a juste un assembleur "intégré" avec des pointeurs bruts et autres.

mannicken
la source
3

Le terme fortement typé n'a pas de définition convenue. Par conséquent, sauf si vous définissez ce que vous voulez dire par « fortement typé », il est impossible de répondre à votre question.

D'après mon expérience, les termes «fortement typé» et «faiblement typé» sont utilisés exclusivement par les trolls, parce que leur manque de définitions permet aux trolls de les redéfinir à mi-parcours en fonction de leur programme. Mis à part pour démarrer des guerres de flammes, ces termes sont pratiquement inutiles.

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

Jörg W Mittag
la source
3
Je ne suis pas d'accord. «Fortement typé» signifie qu'il est possible de déterminer le type de données d'une valeur et que seules les opérations appropriées pour ce type sont autorisées. Indiquer "dynamiquement" et "statiquement" le moment où cette détermination peut être faite.
joel.neely
2
Vous faites réaliser l'ironie d'essayer de réfuter l'affirmation qu'il n'y a pas d' accord sur une définition en introduisant une autre définition, non?
Jörg W Mittag
1
@Jorg: Ne pas essayer d'en introduire un autre; juste en indiquant celui couramment utilisé dans les cercles dans lesquels je me déplace.
joel.neely
1

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

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

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.

Yfeldblum
la source
0

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

BobbyShaftoe
la source
Surtout par curiosité, mais je postule pour un poste C, et je voulais savoir au cas où ils me questionneraient à ce sujet.
Sydius
Alors probablement la réponse plus longue qui donne les nuances de ce que «fortement typé» est la meilleure approche plutôt que de simplement dire «oui» ou «non».
BobbyShaftoe
0

Il est difficile de fournir une réponse concrète quand il n'y a 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 sens qu'il vous permet de changer de type en utilisant des casts et de réinterpréter la représentation d'un type comme un autre.

Robert Gamble
la source
Il y a une def officielle. pour fortement typé. Il dit qu'un fichier sys. est ST quand on garantit qu'il n'y a pas d'erreur de type temps d'exécution. Exemple: ML, Haskell. Ceci est utile pour faire en sorte que le système omette les balises de type à l'intérieur des objets, et cependant appliquer les opérateurs sur les types corrects. Parce que nous savons avant l'exécution qu'il n'y a pas besoin de balises dans les objets. Parce que C a un accès de cast et de pointeur à un mémo arbitraire, C n'est pas st
alinsoar
0

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

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

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

Maintenant, si vous disiez au compilateur d'ignorer les alias stricts, 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 le casting int aussi long et montre vraiment l'un des pièges possibles du vide.

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

Tim Post
la source
0

c est faiblement typé, b est sans type.

plan9assembler
la source
Cette réponse est excessivement courte compte tenu de la question.
Keith Pinson
-1

Pas fortement typé.

Considérez ce que le prototype de fonction suivant vous dit sur les types de données des arguments:

void func (int n, char ch, ...);

Rien. Je suggère donc que le typage fort ne s'applique pas ici.

joel.neely
la source
Hein? Il vous dit qu'il y a un int, suivi d'un caractère, suivi d'un nombre quelconque d'arguments de n'importe quel type. Ce n'est pas "rien".
Lawrence Dol
Le ... ne vous dit rien sur les types d'arguments qui sont passés. Il est vrai que le type de la fonction elle - même est connu. C'est ce que Software Monkey a dit.
Johannes Schaub - litb
Je parle de «n'importe quel nombre d'arguments de n'importe quel type». Une chaîne n'est aussi solide que son maillon le plus faible.
joel.neely
-3

Je dirais que c'est fortement types car chaque expression a un type qui n'est pas fonction de sa valeur; ei, il peut être connu avant l'exécution.

OTOH Je ne suis pas sûr que ce soit la description correcte de fortement typé. La seule affirmation plus forte que je peux voir pour un langage à faire serait l'assurance que vous ne pouvez pas subvertir le système de types au moment de l'exécution via des transtypages de types de réinterprétation, des unions, des appels vers d'autres langues, des pointeurs, un langage d'assemblage, etc. existent mais sont tellement paralysés qu'ils ne semblent pas être d'un grand intérêt pour les programmeurs en dehors de la haute assurance et du monde universitaire. Comme l'a souligné quelqu'un, pour vraiment faire ça correctement, vous commencez à avoir besoin d'avoir des types comme nonZeroIntet autres. Beurk.

BCS
la source
3
Qu'est-ce qui ne l'est pas? Ma définition de fortement typé ou C?
BCS