C è fortemente tipizzato?


88

Per citare Wikipedia :

Due linguaggi comunemente usati che supportano molti tipi di conversione implicita sono C e C ++, e talvolta si afferma che si tratti di linguaggi di tipizzazione debole. Tuttavia, altri sostengono che queste lingue pongono sufficienti restrizioni su come gli operandi di diversi tipi possono essere mescolati, che i due dovrebbero essere considerati come linguaggi fortemente tipizzati.

C'è una risposta più definitiva?


190
Per un programmatore C una digitazione forte significa premere più forte i tasti.
Dan Dyer,

2
C è sul lato debole nel continuum di battitura. Ma ci sono abbastanza elementi su entrambi i lati che puoi discutere in entrambi i casi. Già che ci sei potresti anche chiedere (vi o emacs, netbeans o eclipse, ecc.)
Cervo

4
Lo stato di avanzamento di Wikipedia era così grave che mi sono sentito obbligato a modificare diverse pagine di Wikipedia. Forse adesso le cose vanno un po 'meglio. Può essere.
Norman Ramsey

40
Re: Il commento di Dan (per dare credito a ciò che è dovuto) Il libro di Peter van der Linden "Expert C Programming" contiene la seguente riga: "Fino ad oggi, molti programmatori in C credono che" una digitazione forte significhi solo battere forte sulla tastiera ".
Alexandros Gezerlis

Domanda molto buona !!!
Destructor

Risposte:


154

"Fortemente digitato" e "debolmente digitato" sono termini che non hanno un significato tecnico ampiamente concordato. I termini che hanno un significato ben definito sono

  • Tipizzato dinamicamente significa che i tipi sono associati ai valori in fase di esecuzione e un tentativo di combinare valori di tipi diversi può causare un "errore di tipo in fase di esecuzione". Ad esempio, se in Scheme si tenta di aggiungerne uno a true scrivendo, (+ 1 #t)ciò causerà un errore. Si verifica l'errore solo se si tenta di eseguire il codice offensivo.

  • Digitato staticamente significa che i tipi vengono controllati in fase di compilazione e un programma che non dispone di un tipo statico viene rifiutato dal compilatore. Ad esempio, se in ML si tenta di aggiungerne uno a true scrivendo 1 + true, il programma verrà rifiutato con un messaggio di errore (probabilmente criptico). Ricevi sempre l'errore anche se il codice potrebbe non essere mai eseguito.

Persone diverse preferiscono sistemi diversi a seconda di quanto apprezzano la flessibilità e quanto si preoccupano degli errori di runtime.

A volte "fortemente tipizzato" viene usato liberamente per significare "tipizzato staticamente" e "tipizzato debole" viene usato in modo errato per indicare "tipizzato dinamicamente". Un uso migliore del termine "fortemente tipizzato" è che "non è possibile aggirare o sovvertire il sistema dei tipi", mentre "debolmente tipizzato" significa "ci sono delle scappatoie nel sistema dei tipi". Perversamente, la maggior parte delle lingue con sistemi di tipi statici presenta scappatoie, mentre molti linguaggi con sistemi di tipi dinamici non hanno scappatoie.

Nessuno di questi termini è in alcun modo connesso al numero di conversioni implicite disponibili in una lingua.

Se vuoi parlare precisamente di linguaggi di programmazione, è meglio evitare i termini "fortemente tipizzato" e "debolmente tipizzato". Direi che il C è un linguaggio tipizzato staticamente ma che ha molte scappatoie. Una scappatoia è che puoi lanciare liberamente qualsiasi tipo di puntatore a qualsiasi altro tipo di puntatore. Puoi anche creare una scappatoia tra due tipi qualsiasi di tua scelta dichiarando un'unione C che ha due membri, uno per ciascuno dei tipi in questione.

Ho scritto di più sulla digitazione statica e dinamica sul perché-le-lingue-interpretate-sono-per lo più-dattilografate-mentre-compilate-hanno-digitazione-forte .


2
Dove hai preso le definizioni che suggerisci per la digitazione forte / debole (la cosa della scappatoia)?
Sydius

2
Perché avresti bisogno di una "scappatoia" in un ambiente di digitazione dinamico?
Chris Conway

4
@Sydius: Dopo aver passato gran parte degli ultimi 20 anni a frequentare persone che progettano, costruiscono e analizzano linguaggi di programmazione e sistemi di scrittura. Questo è il mio lavoro retribuito :-)
Norman Ramsey,

@ Chris: non ho mai visto un linguaggio digitato dinamicamente con "scappatoia". L'uso comune di scappatoia è quello di lavorare con un sistema o SO runtime, ad esempio, prendere un indirizzo grezzo e convertirlo in un puntatore a un valore di linguaggio ben educato. Potresti farlo in un ambiente dinamico ma non conosco alcun tentativo.
Norman Ramsey,

1
@NormanRamsey Penso che Chris si riferisse con la sua domanda a:whereas "weakly typed" means "there are loopholes in the type system
Nir Alfasi,

23

È difficile classificare ogni lingua in una digitazione "debole" o "forte": è più un continuum. Ma, rispetto ad altre lingue, C è tipizzato abbastanza fortemente. Ogni oggetto ha un tipo in fase di compilazione e il compilatore ti farà sapere (ad alta voce) se stai facendo qualcosa con un oggetto che il suo tipo non ti consente di fare. Ad esempio, non puoi chiamare funzioni con i tipi di parametri sbagliati, accedere a membri di struct / union che non esistono, ecc

Ma ci sono alcuni punti deboli. Uno dei principali punti deboli sono i typecast: essenzialmente dicono che stai andando a perdere tempo con i tipi di oggetti e il compilatore dovrebbe essere silenzioso (quando può). void*è anche un altro punto debole: è un puntatore generico a un tipo sconosciuto, e quando li usi, devi stare molto attento a fare la cosa giusta. Il compilatore non può controllare staticamente la maggior parte degli usi di void*. void*può anche essere convertito in un puntatore a qualsiasi tipo senza cast (solo in C, non in C ++), che è un altro punto debole.


Bella risposta, anche se "typecast ... e il compilatore dovrebbero tacere" mi dà fastidio. Un typecast non è come disattivare un avviso, in realtà cambia l'interpretazione del valore a cui si fa riferimento.
Tall Jeff,

15
Stai confondendo "statico" e "forte" in relazione alla digitazione. Questi due concetti sono indipendenti l'uno dall'altro.
bendin

1
Dennis Richie (autore C) ha chiamato C 'fortemente tipizzato e debolmente controllato'
TimZaman

11

La letteratura non è chiara su questo. Penso che fortemente digitato non sia sì / no, ci sono vari gradi di digitazione forte.

Un linguaggio di programmazione ha una specifica di come esegue i programmi. A volte non è chiaro come eseguire con determinati programmi. Ad esempio, programmi che tentano di sottrarre una stringa da un numero. O programmi che dividono per zero. Esistono diversi modi per affrontare queste condizioni. Alcune lingue hanno regole per gestire questi errori (ad esempio, generano un'eccezione). Altre lingue semplicemente non hanno regole per affrontare queste situazioni. Questi linguaggi hanno generalmente sistemi di tipi per impedire la compilazione di programmi che portano a comportamenti non specificati. E esistono anche linguaggi che hanno un comportamento non specificato e non hanno un sistema di tipi per prevenire questi errori in fase di compilazione (se scrivi un programma che ha un comportamento non specificato potrebbe lanciare i missili).

Così:

Le lingue che specificano ciò che accade in fase di esecuzione in ogni caso (come l'aggiunta di un numero a una stringa) sono chiamate digitate dinamicamente. I linguaggi che impediscono l'esecuzione di programmi con errori in fase di compilazione sono tipizzati staticamente. Le lingue che non specificano cosa succede e che non dispongono di un sistema di tipi per evitare errori sono chiamate debolmente tipizzate.

Quindi Java è tipizzato staticamente? Sì, perché il suo sistema di tipi non consente di sottrarre una stringa da un numero. No, perché ti permette di dividere per zero. È possibile impedire la divisione per zero in fase di compilazione con un sistema di tipi. Ad esempio creando un tipo di numero che non può essere zero (ad esempio NonZeroInt) e consente solo di dividere per numeri che hanno questo tipo.

Quindi il C è fortemente tipizzato o debolmente tipizzato? C è fortemente tipizzato perché il sistema di tipi non consente alcuni errori di tipo. Ma è debolmente digitato in altri casi quando non è definito ciò che accade (e il sistema di tipi non ti protegge).


Mi piace il tuo allineamento tra dinamico e statico come forme di forte e debole. Tuttavia, non sono sicuro di aver capito il tuo punto di vista sui sistemi tipizzati staticamente che interrompono la divisione per zero. Se il mio digitato staticamente intottiene un valore dall'utente o dagli argomenti della riga di comando o da un file, non c'è nulla che il compilatore possa fare per impedire che sia uno zero!
Rikki

1
Esistono sistemi di tipo statico che lo impediscono, ma la maggior parte dei linguaggi è debolmente o dinamicamente "tipizzata" rispetto alla divisione per zero, perché è un comportamento indefinito (C) o genera un'eccezione (Java).
Jules

11

C è considerato debolmente tipizzato, perché puoi convertire qualsiasi tipo in qualsiasi altro tipo tramite un cast, senza un errore del compilatore. Puoi leggere di più sul problema qui .


2
wikipedia è fuorviante qui. C è fortemente tipizzato, i tipi sono molto validi e il compilatore sbaglierà se li sbagli, tuttavia, C fornisce anche funzionalità per bypassare questo. Confronta con linguaggi come BCPL che hanno solo un tipo "byte".
gbjbaanb

13
Digitato debolmente non significa che una lingua non abbia alcun tipo, significa solo che i tipi possono essere implicitamente forzati da un tipo a un altro. Confronta con Python, un linguaggio fortemente tipizzato in cui devi convertire esplicitamente i tipi con chiamate di funzione.
mipadi

anche la capacità di lanciare una cosa in C contribuisce a renderlo un tipo debole. ?? Ho questo dubbio come per sempre
Suraj Jain

8

C è più tipizzato di Javascript e meno tipizzato di Ada.

Direi che rientra maggiormente nel lato fortemente tipizzato del continuum. ma qualcun altro potrebbe non essere d'accordo (anche se si sbaglia).

Che ne dici di definitivo?


Era una risposta un po 'ironica. Ma approfondisci l'erroneità.
Michael Burr

1
Javascript è fortemente tipizzato. Semplicemente non è digitato staticamente. Tutti i controlli di tipo avvengono in fase di esecuzione (dinamico, non statico) ma si verificano e impediscono di danneggiare la memoria (un aspetto della digitazione forte).
bendin

5
Ebbene, come indica l'ottima risposta di Norm Ramsey, "fortemente tipizzato" e "debolmente tipizzato" non sono termini particolarmente ben definiti. Inoltre, per quanto Javascript sia fortemente tipizzato, alcuni potrebbero credere che ("4" / ​​"2") un'espressione Javascript valida potrebbe indicare il contrario.
Michael Burr

5

C è considerato tipizzato staticamente (non è possibile modificare la variabile da int a float). Una volta che una variabile è stata dichiarata, viene bloccata in questo modo.

Ma è considerato debolmente tipizzato perché i tipi possono essere flip flop.

Cos'è 0? "\ 0", FALSE, 0.0 e così via.

in molte lingue non è possibile dire IF (variabile) perché le condizioni prenderanno solo valori booleani da espressioni booleane. Questi sono tipizzati più fortemente. Lo stesso vale per il passaggio tra caratteri e numeri interi.

fondamentalmente c ha due principali tipi di dati semplici, interi e numeri in virgola mobile (sebbene varie precisioni). Tutto il resto booleane, enumerazioni (non semplici ma adatte), ecc. Sono implementati come uno di questi. Anche i caratteri sono fondamentalmente numeri interi.

Confronta con altri linguaggi in cui sono presenti tipi stringa, tipi enum che possono essere assegnati solo ai valori definiti, tipi booleani in cui possono essere utilizzate solo espressioni che generano booleani o vero / falso.

Ma si può sostenere che rispetto a Perl C è fortemente tipizzato. Quindi è uno di quei famosi argomenti (vi vs emacs, linux vs windows, ecc.). C # è un tipo più forte di C. Fondamentalmente puoi discutere in entrambi i modi. E le tue risposte probabilmente andranno in entrambe le direzioni :) Inoltre alcuni libri di testo / pagine web diranno che C è digitato in modo debole, e alcuni diranno che C è fortemente digitato. Se vai su wikipedia la voce C dice "tipizzazione parzialmente debole". Direi che rispetto a Python C è debolmente tipizzato. Quindi Python / C #, C, Perl sul continuum.


Per favore spiega il tuo ragionamento secondo cui Perl è tipizzato in modo meno forte di C.
user51568

print "Testing" + 0 # perl farà 0; $ var = "stringa"; $ var = 1; $ var = 123,4; Che tipo di variabile è?
Cervo

In C char * test = "testing"; printf (test + 0); sarà ancora una stringa, è solo che in C l'indice cambierà se invece di zero uso un numero. È ancora piuttosto debole, ma un po 'più forte di Perl. char * test; test = 0; test = 123,4; test = "c"; ... il mio compilatore genera errori
Cervo

l'errore dice che è richiesto un cast. Tuttavia è un po 'più forte di un controllo di tipo rispetto a Perl, quindi sul continuum devo dire che C è più fortemente tipizzato di Perl. Puoi ancora andare test = (char *) e quindi usare 0, 123.4, 'C', ecc. Ma è un errore farlo.
Cervo

4

Molte buone risposte qui. Voglio sollevare un punto importante da Real World Haskell :

È utile essere consapevoli che molte comunità linguistiche hanno le proprie definizioni di "tipo forte". Tuttavia, parleremo brevemente e in termini generali della nozione di forza nei sistemi di tipi.

(snip)

I fuochi d'artificio attorno ai sistemi di caratteri hanno le loro radici nell'inglese comune, dove le persone attribuiscono nozioni di valore alle parole "debole" e "forte": di solito pensiamo alla forza come meglio della debolezza. Molti più programmatori parlano un inglese semplice rispetto al gergo accademico, e molto spesso gli accademici lanciano davvero blocchi contro qualsiasi tipo di sistema non si adatti alla loro fantasia. Il risultato è spesso quel popolare passatempo di Internet, una guerra con le fiamme.

Quindi, guarda le risposte su C e C ++, ma ricorda che "forte" e "debole" non si associano a "buono" e "cattivo".


4

Secondo Dennis Ritchie ( creatore di C ) e Brian Kernighan, il C non è un linguaggio fortemente tipizzato. Le righe seguenti sono tratte dal libro Il linguaggio di programmazione C pagina 3 paragrafo 5

Il C non è un linguaggio fortemente tipizzato, ma man mano che si è evoluto, il suo controllo del tipo è stato rafforzato.


3

A mio parere, C / C ++ sono fortemente tipizzati. I tipi di hack che consentono di convertire i tipi (void *) esistono a causa della vicinanza di C alla macchina. In altre parole, puoi chiamare comandi assembler da Pascal e manipolare puntatori e Pascal è ancora considerato un linguaggio fortemente tipizzato. Puoi chiamare l'assembler e gli eseguibili C da Java tramite JNI ma non rende Java debolmente tipizzato.

C ha semplicemente l'assembler "incorporato" in esso con puntatori grezzi e simili.


3

Il termine fortemente tipizzato non ha una definizione concordata. Pertanto, a meno che tu non definisca cosa intendi per "fortemente tipizzato", è impossibile rispondere alla tua domanda.

Nella mia esperienza, i termini "fortemente tipizzato" e "debolmente tipizzato" sono usati esclusivamente dai troll, perché la loro mancanza di definizioni consente ai troll di ridefinirli a metà argomento per adattarli alla loro agenda. Oltre a far partire le guerre con le fiamme, questi termini sono praticamente inutili.

Potresti anche dare un'occhiata a Quali sono gli aspetti chiave di un linguaggio fortemente tipizzato? qui su StackOverflow.


3
Non sono d'accordo. "Strongly typed" significa che è possibile determinare il tipo di dati di un valore e sono consentite solo le operazioni appropriate per quel tipo. Indirizzare "dinamicamente" e "staticamente" quando tale determinazione può essere effettuata.
joel.neely

2
Si fa realizzare l'ironia di cercare di confutare l'affermazione che non v'è definizione univoca con l'introduzione di un ulteriore definizione, giusto?
Jörg W Mittag,

1
@ Jorg: Non sto cercando di presentarne un altro; precisando solo quello comunemente usato nei cerchi in cui mi muovo.
joel.neely

1

Esiste un continuum con molteplici vie parallele tra "debolmente tipizzato" e "fortemente tipizzato", due termini che non sono nemmeno ben definiti.

C è tipizzato staticamente , in quanto il compilatore sa qual è il tipo dichiarato di ogni variabile locale e membro della struttura.

I linguaggi tipizzati dinamicamente potrebbero ancora essere tipizzati fortemente, se ogni oggetto ha un tipo specifico ma non c'è modo per il compilatore di conoscere quel tipo.


0

Qual è il motivo della tua domanda? Il motivo per cui lo chiedo è che questa è una specie di piccola differenza e il tuo uso particolare di "fortemente tipizzato" potrebbe richiedere più o meno chiarimenti. Direi sicuramente che Java e altri linguaggi hanno restrizioni più rigide sulla conversazione di tipo implicito.


Principalmente curiosità, ma mi candido per una posizione C e volevo sapere nel caso mi chiedessero qualcosa.
Sydius

Quindi probabilmente la risposta più lunga che dà le sfumature di ciò che "fortemente digitato" è l'approccio migliore piuttosto che dire semplicemente "sì" o "no".
BobbyShaftoe

0

È difficile fornire una risposta concreta quando non esiste una definizione concreta di "fortemente tipizzato". Direi che C è fortemente tipizzato in quanto ogni variabile e ogni espressione ha un tipo ma debolmente tipizzato in quanto ti permette di cambiare tipo usando i cast e di reinterpretare la rappresentazione di un tipo come un altro.


C'è una def. per fortemente tipizzato. Dice che un file sys. è ST quando si garantisce che non vi sia alcun errore di tipo tempo di esecuzione. Esempio: ML, Haskell. Ciò è utile per fare in modo che il sistema ometta i tag di tipo all'interno degli oggetti, e tuttavia applica gli operatori sui tipi corretti. Perché sappiamo prima dell'esecuzione che non c'è bisogno di tag negli oggetti. Poiché C ha accesso al cast e al puntatore di un memo arbitrario, C non è st
alinsoar

0

Direi che C è fortemente tipizzato come impone il tuo compilatore / piattaforma. Ad esempio, se stai costruendo su una piattaforma rigida, è probabile che la dereferenziazione di un puntatore con punte di tipo si interrompa:

Ora, se dicessi al compilatore di saltare l'aliasing rigoroso, non sarebbe un problema, ma non molto portabile. Quindi, in quel senso, spingersi oltre i limiti del linguaggio è possibile ma probabilmente non è l'idea migliore. Questo va un passo oltre il tipico casting, cioè casting int il più a lungo e mostra davvero una delle possibili insidie ​​del vuoto.

Quindi, direi che C è fondamentalmente strettamente tipizzato, ma i suoi vari compilatori presumono che il programmatore lo sappia meglio e consenta una certa flessibilità. Questo dipende davvero dal compilatore, alcuni non avrebbero capito quel potenziale oops. Quindi, in questo senso, il compilatore scelto gioca davvero un ruolo quando risponde alla domanda. Ciò che è corretto spesso è diverso da ciò con cui il tuo compilatore ti permetterà di cavartela.



-1

Non fortemente digitato.

Considera cosa ti dice il seguente prototipo di funzione sui tipi di dati degli argomenti:

Niente. Quindi suggerisco che la digitazione forte non si applica qui.


Eh? Ti dice che c'è un int, seguito da un carattere, seguito da un numero qualsiasi di argomenti di qualsiasi tipo. Non è "niente".
Lawrence Dol

Il ... non ti dice nulla sui tipi di argomenti passati. È vero che il tipo di funzione stessa è noto. Questo è ciò che ha detto Software Monkey.
Johannes Schaub - litb

Sto parlando di "qualsiasi numero di argomenti di qualsiasi tipo". Una catena è forte quanto il suo anello più debole.
joel.neely

-3

Direi che è fortemente types poiché ogni espressione ha un tipo che non è una funzione del suo valore; ei può essere conosciuto prima del runtime.

OTOH Non sono sicuro che sia la descrizione corretta di fortemente digitato. L'unica affermazione più forte che posso vedere perché un linguaggio dovrebbe fare sarebbe la certezza che non è possibile sovvertire il sistema di tipi in fase di esecuzione reinterpretando cast di tipo, unioni, chiamate in altri linguaggi, puntatori, linguaggio assembly, ecc. Linguaggi come questo esistono ma sono così paralizzati che sembrano non interessare molto ai programmatori al di fuori dell'alta certezza e del mondo accademico. Come sottolineato da qualcuno, per farlo davvero nel modo giusto inizi a dover avere tipi come nonZeroInte quant'altro. Che schifo.


3
Cosa non lo è? La mia definizione di fortemente tipizzato o C?
BCS
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.