È il C++ considerato debolmente tipizzato? Perché?

Ho sempre considerato la C++ per essere uno dei più fortemente tipizzato lingue là fuori.
Quindi ero molto scioccato per vedere Tabella 3 di questa carta stato che il C++ è debolmente tipizzato.

A quanto pare,

C e C++ sono considerati debolmente tipizzato dal momento che, a causa del tipo di casting, si può interpretare un campo di una struttura che è un numero intero come un puntatore.

È l’esistenza di tipo colata tutto ciò che conta? Fa esplicito-ness di tali cast non importa?

Più in generale, è davvero generalmente accettato che il C++ è debolmente tipizzato? Perché?

  • C++ non è debolmente tipizzato, ma è in grado di sovvertire il tipo di sistema, se si desidera. Quindi, si potrebbe affermare che essa non è completamente fortemente tipizzato.
  • .. e se permette (tipo giocando è difficile)
  • Così come è C# considerati fortemente tipizzato? Non si può fare esattamente la stessa cosa con unsafe o utilizzando il Marshal classe?
  • Penso che “debolmente tipizzato” è un termine soggettivo. “Tipizzata” e “staticamente tipizzato” vs. “digitati” e “dinamicamente tipizzato” sono più obiettivi, più precise parole. Da quello che posso dire, in generale la gente usa “debolmente tipizzato” come un diminutivo-peggiorativo termine che significa “non mi piace l’idea di tipi in questa lingua”. E ‘ una specie di un argumentum ad hominem (o meglio, argumentum ad linguam) per coloro che non possono portare professionale-tecnico di argomenti contro una determinata lingua.
  • Vedo. Così che cosa sarebbe “tipizzata” significa?
  • Anche la citazione sarebbe suggeriscono che può essere digitato in modo dinamico, piuttosto che debolmente tipizzato.
  • Io credo che si possa fare int x = false; perché il C++ permette la conversione tra bool e int (nota che il compilatore può AVVERTIRE su di esso, ma se non è un errore, quindi il linguaggio debolmente tipizzato, almeno quando si tratta di bool e int combinazioni)
  • Ha anche leggermente diverse interpretazioni; generalmente accettati significato è “il compilatore genera errori, se i tipi non sono all’altezza”. Un’altra interpretazione è che “ci sono pochi o nessun conversioni implicite”. Sulla base di questo, C++ può effettivamente essere considerato un tipizzata in lingua, e il più delle volte è considerato come tale.
  • Inoltre, ci sono alcuni programmatori, specialmente i principianti non hanno familiarità con un sacco di lingue, che non intendono o non possono fare distinzione tra “rigorosa” e “statico”, “sciolto” e “dinamico”, e confondere le due altrimenti ortogonali – concetti di base su di loro limitata esperienza (io. e. la correlazione di dinamismo e di sciogliere, digitando popolari linguaggi di scripting, per esempio). In realtà, parti di C++ (virtuale chiamate) imporre l’obbligo che il tipo di sistema di essere parzialmente dinamico, ma le altre cose nella norma richiede di essere rigorosi. Di nuovo, questo non è un problema.
  • Bjarne Stroustrup libro menziona che il C++ è un linguaggio fortemente tipizzato a pagina 2. Che dovrebbe sapere meglio di lui 🙂
  • Penso che vale la pena sottolineare che gli avvisi possono anche essere promossa a errori (-Werror con g++ per esempio).

InformationsquelleAutor Mehrdad | 2014-11-05

 

5 Replies
  1. 25

    Che la carta prima reclami:

    In contrasto, un linguaggio debolmente tipizzato se il tipo di confusione può verificarsi in silenzio (inosservato), e, infine, provocare errori che sono difficili da localizzare.

    E poi afferma:

    Inoltre, C e C++ sono considerati debolmente tipizzato dal momento che, a causa del tipo di casting, si può interpretare un campo di una struttura che è un numero intero come un puntatore.

    Questa sembra una contraddizione per me. In C e C++, il tipo di confusione che può verificarsi come risultato di cast non si verifica in silenzio-c’è un cast! Questo non dimostra che una di queste lingue è debolmente tipizzato, almeno non nella definizione di quella carta.

    Che ha detto, per la definizione della carta, C e C++ può essere considerato ancora debolmente tipizzato. Ci sono, come indicato nei commenti sulla questione già, i casi in cui il linguaggio supporta le conversioni di tipo implicito. Molti tipi possono essere convertiti in modo implicito bool, un letterale zero di tipo int può essere convertito in silenzio per qualsiasi tipo di puntatore, ci sono conversioni tra numeri interi di varie dimensioni, ecc, quindi questo mi sembra un buon motivo per considerare C e C++ debolmente tipizzato per le finalità della carta.

    Per C (ma non C++), ci sono anche più pericolose le conversioni implicite che sono degni di nota:

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

    Per le finalità della carta, che deve essere certamente considerato debolmente tipizzato. La reinterpretazione di bit avviene nel silenzio, e può essere fatto molto peggio modificando per utilizzare completamente estranei tipi, che ha silenzioso comportamenti indefiniti, che in genere ha lo stesso effetto come una reinterpretazione di bit, ma esplode nel misterioso ma a volte divertenti modi quando ottimizzazioni sono abilitati.

    In generale, però, penso che non ci sia una definizione fissa di “tipizzata” e “debolmente tipizzato”. Ci sono vari gradi, un linguaggio fortemente tipizzato rispetto per il montaggio possono essere debolmente tipizzato rispetto al Pascal. Per determinare se il C o il C++ è debolmente tipizzato, è necessario prima di chiedere ciò che si desidera debolmente tipizzato per dire.

    • +1 grande punto. Ma per rispondere alla domanda, si dovrebbe anche parlare di se o non il C++ è fortemente tipizzato da qualunque sia la definizione più accettata è!
    • +1 bella cattura wrt la contraddizione!
    • Concordato, e ampliato la mia risposta.
    • Fantastico, grazie! 🙂
    • Cast in C e C++ può verificarsi in silenzio, si sa. In realtà, entrambe le lingue sono piena di sottile tipo di trappole. Nella mia esperienza, la maggior parte delle chiamate di printf (e la famiglia), scritto da una media programmatore C/C++ contenere un comportamento indefinito 🙂
    • No, non può. “Cast” significa “conversione esplicita” (o, più specificatamente, la sintassi utilizzata per la scrittura di una conversione esplicita). Ci sono le conversioni implicite, come ho già scritto nella mia risposta, ma non sono chiamati cast.
    • Pericoloso per le conversioni non si verificano in modo implicito in C++, ma lo fanno in C (ad es. puntatore conversioni).
    • Ah, sì, penso che potrebbe essere un buon punto lì. Devo aggiungere che la mia risposta.
    • È vero, il linguaggio C/C++-avvocato punto di vista. Tuttavia, anche quelli di noi che solo programmare in C e C++ a volte laxly utilizzare la parola “cast” con il significato di ‘conversione’.
    • Se è quello che gli autori della carta significato, allora sono d’accordo che si dispone di un buon punto, ma l’impressione che ho avuto è che dopo void *p = ...; int i = (int)p;.
    • Mehrdad, purtroppo, devo dissentire. int i; printf("%p, %i", &i, sizeof i);. Ci sono due tipo di sistema violazioni in questo semplice codice.
    • Credo di parlare la stessa lingua, non la libreria standard. Se si guarda in quel modo, si potrebbe anche pretendere che ogni linguaggio che permette di chiamare le funzioni C che permette pericoloso conversioni.
    • ma si può scrivere un’implementazione di printf te, e non sarebbe comunque la stessa vulnerabilità. Quindi è il linguaggio che provoca questi tipo di violazione.
    • No. I miei obiettivi sono quelli di vulnerabilità, se si utilizza varargs, ma va_arg esegue una conversione esplicita, non un implicito uno.
    • non si poteva evitare l’uso di varargs prima di C++11 implementare printf, impossibile?
    • Per il C++ (ma non C), ci sono anche più pericolose le conversioni implicite che sono degni di nota: la Creazione di un array di classe derivata (Derived a[10]), poi passare a una funzione che prende un array di base di classe (void f(Base x[]); f(a);). Guarda che crash e bruciare. In altre parole, l’implicita Derived * per Base * di conversione è a rischio a causa dell’esistenza dei nativi matrici.
    • Credo che una distinzione che non viene fatta qui (nonostante il fatto che molte persone qui sono esperti e consapevoli), è al di là di differenze tecniche in C e C++ (legale conversioni), c’è un’enorme differenza nella forza di digitare idiomatiche codice. Per esempio, C ellissi di argomenti legali, C++, ma non idiomatiche (sostituito da modelli variadic che sono fortemente tipizzati). Un altro esempio: utente-stateful richiamate C sono gestite dalla funzione di puntatore tenendo void*. In C++ gestito dalla funzione di oggetto/std::function. Generalmente void* utilizzo in C++ è molto, molto più raro. Ecc.
    • Il tuo esempio è del compilatore-saggio di grande ma non a raggiungere un evidente fallimento.

  2. 7

    “debolmente tipizzato” è un termine soggettivo. Io preferisco i termini “tipizzata” e “staticamente tipizzato” vs “digitati” e “dinamicamente tipizzati”, perché sono più obiettivi e più precise parole.

    Da quello che posso dire, in generale, non utilizzare “debolmente tipizzato” come un diminutivo-peggiorativo termine che significa “non mi piace l’idea di tipi in questa lingua”. E ‘ una specie di un argumentum ad hominem (o meglio, argumentum ad linguam) per coloro che non possono portare tecnico o professionale argomenti contro una determinata lingua.

    Il termine “tipizzata” ha anche leggermente diverse interpretazioni; generalmente accettati significato, nella mia esperienza, è “il compilatore genera errori, se i tipi non sono all’altezza”. Un’altra interpretazione è che “ci sono pochi o nessun conversioni implicite”. Sulla base di questo, C++ può effettivamente essere considerato un tipizzata in lingua, e il più delle volte è considerato come tale. Direi che il consenso generale sul C++ è che è strettamente linguaggio tipizzato.

    Naturalmente, si potrebbe provare un approccio efficace alla domanda e dire che le parti del linguaggio sono fortemente tipizzati (questa è la maggioranza dei casi), altre parti sono digitati (un paio di conversioni implicite, e. g. conversioni aritmetiche e i quattro tipi di conversione esplicita).

    Inoltre, ci sono alcuni programmatori, soprattutto per i principianti che non sono familiari con più di un paio di lingue, che non intendono o non possono fare distinzione tra “rigorosa” e “statico”, “sciolto” e “dinamico”, e confondere le due altrimenti ortogonali – concetti basati sulla loro esperienza limitata (di solito la correlazione di dinamismo e di sciogliere, digitando popolari linguaggi di scripting, per esempio).

    In realtà, parti di C++ (virtuale chiamate) imporre l’obbligo che il tipo di sistema di essere parzialmente dinamico, ma le altre cose nella norma richiede di essere rigorosi. Di nuovo, questo non è un problema, dal momento che questi sono concetti ortogonali.

    Per riassumere: probabilmente nessuna lingua si adatta completamente, perfettamente in una categoria o in un altro, ma possiamo dire che particolare struttura di una determinata lingua domina. In C++, rigore, sicuramente non dominare.

  3. 2

    In contrasto, un linguaggio debolmente tipizzato se il tipo di confusione può verificarsi in silenzio (inosservato), e, infine, provocare errori che sono difficili da localizzare.

    Bene, che può accadere in C++, per esempio:

    #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
    }

    Inoltre, C e C++ sono considerati debolmente tipizzato dal momento che, a causa del tipo di casting, si può interpretare un campo di una struttura che è un numero intero come un puntatore.

    Ummmm… non tramite qualsiasi conversione implicita, in modo che una stupida argomento. Il C++ permette il casting esplicito fra i tipi, ma non è “debole” – non capita accidentalmente/in silenzio, come richiesto dal sito della propria definizione di cui sopra.

    È l’esistenza di tipo colata tutto ciò che conta? Fa esplicito-ness di tali cast non importa?

    Esplicitazione è un ruolo fondamentale IMHO. Lasciando un programmatore ignorare il compilatore conoscenza delle tipologie è il “potere” di C++, non una debolezza. Non è soggetta a uso accidentale.

    Più in generale, è davvero generalmente accettato che il C++ è debolmente tipizzato? Perché?

    No – io non credo che sia accettato. Il C++ è ragionevolmente fortemente tipizzato, e i modi in cui esso è stato indulgente che storicamente hanno causato problemi sono stati potati indietro, come cast impliciti da void* ad altri tipi di puntatore, e affinare il controllo con explicit casting operatori e costruttori.

  4. 0

    Bene, poiché il creatore del C++, Bjarne Stroustrup dice in Il Linguaggio di Programmazione C++ (4 ° edizione) che il linguaggio è fortemente tipizzato, vorrei prendere la sua parola:

    Di programmazione C++ è basato su un forte controllo di tipo statico, e la maggior parte delle tecniche mirano a conseguire un elevato livello di astrazione e di una rappresentanza diretta del programmatore di idee. Questo di solito può essere fatto senza compromettere esecuzione e di efficienza in termini di spazio rispetto per abbassare il livello di tecniche. Per ottenere i benefici di C++, programmatori provenienti da una lingua diversa deve
    imparare e interiorizzare idiomatiche stile di programmazione C++ e tecnica. Lo stesso vale per i programmatori utilizzato per la precedente e meno espressivo versioni di C++.

    In questo video conferenza dal 1994 afferma, inoltre, che il debole sistema di tipo C veramente fastidio di lui, e per questo motivo ha fatto il C++ fortemente tipizzato: Il Design del C++ , conferenza di Bjarne Stroustrup

  5. -4

    Permettetemi di darvi un esempio semplice:

     if ( a + b )

    C/C+= permette una conversione implicita da float a int Boolean.

    Un linguaggio fortemente tipizzato non avrebbe permesso ad una conversione implicita.

Lascia un commento