Perché i sistemi operativi fanno cose di basso livello in C e C ++? Perché non solo C ++?

20

Nella pagina di Wikipedia per Windows , si afferma che Windows è scritto in Assembly per il bootloader e lo switcher di attività, e C e C ++ per le routine del kernel.

IIRC, puoi chiamare le funzioni C ++ da un blocco di extern "C" 'd. Posso usare C per le funzioni del kernel in modo che le app C possano utilizzarle (come printf e così), ma se possono essere semplicemente racchiuse in un blocco extern "C " , allora perché scrivere in C?

    
posta Cole Johnson 10.12.2012 - 18:32
fonte

13 risposte

31

È principalmente per ragioni storiche. Alcune parti del kernel di Windows sono state originariamente scritte in C, perché nel 1983, più di trent'anni fa, quando Windows 1.0 è stato rilasciato , C ++ è stato appena rilasciato. Ora queste librerie C rimarranno "per sempre", perché Microsoft ha reso la retrocompatibilità un punto di forza e riscrivere una versione compatibile con gli errori dei componenti C in C ++ richiede un enorme sforzo per nessun beneficio effettivo.

    
risposta data 10.12.2012 - 18:58
fonte
24

Come molte persone hanno sottolineato, le ragioni sono di gran lunga storiche, ma c'è qualcos'altro che nessuno menziona e credo che sia la ragione per cui le persone scrivono ancora codice C per basso livello.

C è un linguaggio piccolo nel senso che la specifica è (relativamente) breve. C ++ è enorme e questo è un eufemismo. Questo potrebbe non essere importante per il programmatore (anche se penso che lo sia), ma è estremamente importante se si desidera eseguire verifica formale . Inoltre ci sono strumenti consolidati per l'analisi del codice C, che potrebbero aiutare a prevenire bug, ecc.

E questo è molto importante nel software embedded, dove il costo di un bug che viene distribuito è estremamente elevato, rispetto al resto del settore (confrontare Web, dove è possibile applicare immediatamente una patch a tutti gli utenti). Per non parlare di software mission-critical e materiale medico.

Ci sono stati tentativi di spostare C dalla sua posizione dominante nella programmazione di basso livello con linguaggi che sono ancora migliori in questo, come BitC, ma finora non hanno avuto successo.

    
risposta data 11.12.2012 - 01:33
fonte
15
  1. Il runtime C è molto più piccolo.
  2. La traduzione di C ++ in costrutti di livello inferiore è meno trasparente rispetto a C. (Vedi riferimenti e vtables, per due esempi rapidi)
  3. C di solito ha un ABI stabile. C ++ di solito no. Ciò significa che, al minimo, l'interfaccia di chiamata di sistema dovrebbe essere in stile C. Inoltre, se vuoi un qualsiasi tipo di modulo dinamico, avere un ABI coerente aiuta molto.
risposta data 11.12.2012 - 08:17
fonte
11

Le ragioni non sono tecniche. Un po 'di assemblaggio è inevitabile, ma non sono forzati per usare l'occasionale C, a cui vogliono . La mia azienda usa il proprio kernel proprietario, scritto quasi interamente in C ++, ma non abbiamo bisogno di supportare un'interfaccia C per il kernel come molti altri, perché il nostro kernel incorporato è compilato monoliticamente con le nostre applicazioni C ++. Quando hai un'interfaccia C, è spesso più facile scrivere il codice dell'interfaccia in C, anche se è possibile per usare extern "C" per scriverlo in C ++.

Anche noi abbiamo un'infarinatura di file C, principalmente a causa del codice di terze parti. Il codice di basso livello di terze parti è quasi sempre fornito in C, perché è molto più semplice incorporare il codice C in un'app C ++ rispetto al contrario.

    
risposta data 10.12.2012 - 19:21
fonte
6

Gli sviluppatori di kernel sono spesso il tipo di persone, che si sentono più felici, quando è immediatamente evidente dalla fonte, cosa fa effettivamente il codice.

C ++ ha molte più funzionalità, che nascondono ciò che il codice fa più del semplice codice C lo nasconde: overload, metodi virtuali, template, riferimenti, lanci ... C ++ ha anche una sintassi molto più ampia che devi padroneggiare per pareggiare capisci il codice C ++ che lo usa.

Penso che il potere del C ++ sia uno strumento molto potente per creare librerie e framework, che rendono quindi lo sviluppo di applicazioni molto veloce. Molto spesso lo sviluppatore di applicazioni C ++ si perderebbe completamente nelle interi di una libreria riempita di modelli, anche quando è molto competente nella creazione di applicazioni che utilizzano quella libreria. Scrivere una libreria C ++ è un compito di programmazione molto impegnativo, e fatto solo per fornire un ottimo framework a beneficio dello sviluppatore dell'applicazione. Le librerie C ++ non sono semplici internamente, sono (o possono essere ...) semplicemente potenti ma semplici dal punto di vista dei programmatori di applicazioni.

Ma l'API del kernel non può essere un'API C ++, deve essere un'API indipendente dal linguaggio, quindi la maggior parte delle cose carine in C ++ non sarebbero direttamente utilizzabili in quell'interfaccia. Inoltre, il kernel non è realmente suddiviso in parti "library" e "application" sviluppate in modo indipendente, con un maggiore sforzo logico in una libreria, per semplificare la creazione di una massa di applicazioni.

Inoltre, la sicurezza e la stabilità sono più critiche all'interno di un kernel, ei metodi virtuali sono molto più dinamici e quindi molto più difficili da isolare e verificare, piuttosto che semplici callback o altri meccanismi simili a C.

In breve, mentre potreste ovviamente scrivere qualsiasi programma C incluso un kernel come C ++, la maggior parte della potenza del C ++ non è ben usata nel kernel. E molti sostengono che gli strumenti di programmazione dovrebbero impedirti di fare cose che non dovresti fare. C ++ no.

    
risposta data 11.12.2012 - 14:37
fonte
5

Bjarne Stroustrup, in un'intervista nel luglio 1999 :

None of these languages was radically different or dramatically better than other contemporary languages. They were, however, good enough and the beneficiaries of luck and social factors

    
risposta data 11.12.2012 - 06:39
fonte
3

C è un linguaggio di livello molto basso, dal suo design. È ad un passo dall'assemblatore; conoscendo il chipset che hai scelto, potresti, con un po 'di conoscenza, "compilare" manualmente C in ASM. Questo tipo di linguaggio "close-to-the-metal" è la chiave per alti livelli di ottimizzazione (per prestazioni, memoria-efficienza, ecc.). Tuttavia, poiché è così vicino al metallo, non si ottiene molto gratis con questo linguaggio; è un linguaggio procedurale, non orientato agli oggetti, e quindi lavorare con tali costrutti coinvolge un sacco di codice boilerplate per creare e consumare costrutti multivalore in memoria.

C ++ è "C one better", aggiungendo una serie di funzioni di facile utilizzo come l'allocazione dinamica della memoria, il marshalling di strutture incorporato, una vasta libreria di codice predefinito, ecc., a scapito di alcuni perdite di efficienza (ancora molto meglio degli ambienti di runtime gestito). Per il codificatore medio, i vantaggi superano di gran lunga gli svantaggi nelle aree del codebase che non richiedono il controllo anale-ritentivo dell'allocazione di memoria ecc.

La combinazione dei due è piuttosto tradizionale; si utilizza C per scrivere le aree più critiche in termini di prestazioni e di memoria della base di codice, che è possibile quindi lavorare in modo più astratto tramite chiamate di metodo dal codice C ++, che possono essere organizzate e progettate in modo più elegante rispetto alle uber-performant , codice C ottimizzato ottimamente.

    
risposta data 10.12.2012 - 19:13
fonte
1

Potrebbe essere che con C passi la maggior parte del tuo tempo a pensare al problema in questione e a come codificare la soluzione. In C ++ si finisce per pensare a C ++ e alla sua miriade di funzioni, funzioni e sintassi oscure.

Anche in molti negozi C ++ il tuo codice viene monitorato dalla "polizia della moda" che è affascinata dall'ultima serie di modelli di design o dalle ultime dichiarazioni incomprensibili del grande dio Stroustrup. Il codice grazioso diventa più prezioso del codice di lavoro, trovare un utilizzo per l'ultimo set di modelli Boost è più ammirato che trovare una soluzione funzionante per il business.

La mia esperienza è che con tutte le funzionalità intelligenti e la purezza OO del C ++, la codifica in chiaro C fa il lavoro più veloce ed efficacemente.

    
risposta data 06.02.2013 - 02:52
fonte
0

È possibile che le parti C non siano facilmente trasferibili al compilatore C ++ utilizzato per le parti C ++. Forse il codice C è scadente con il compilatore C in modi che rompono con il compilatore C ++.

Se hai un compilatore C ++ di qualità, non c'è quasi alcun motivo per mescolare C e C ++ in un progetto. Quasi.

L'unica ragione potrebbe essere che il tuo progetto condivide il codice C con altri progetti, il codice non viene compilato come C ++ e non vuoi mantenere un fork C ++ di quel codice.

    
risposta data 11.12.2012 - 06:54
fonte
-1

Penso di averlo indietro - il blocco extern "C" garantisce che le convenzioni di chiamata C vengano utilizzate per tutte le funzioni all'interno del blocco. Quindi puoi chiamare pure funzioni C da C ++, non funzioni C ++ da C. Indipendentemente da ciò, immagino che la ragione per cui le persone usano sia C che C ++ è perché molte librerie di basso livello sono scritte usando C, ed è più facile usare qualcosa che esiste già (e presumibilmente è debugato e ottimizzato) rispetto alla scrittura personale. OTOH, C ++ offre molte funzioni di alto livello con cui le persone preferiscono lavorare, quindi lo usano per il resto.

    
risposta data 10.12.2012 - 18:47
fonte
-2

Ci sono vari livelli di piattaforme embedded che usano C come linguaggio di programmazione (ovviamente è tua libertà usare il linguaggio assembly in qualsiasi momento)

Per "Livello", sto parlando del livello di risorse SRAM e ROM interne per un sistema.

Talvolta queste piattaforme sono limitate da risorse (ad esempio alcune piattaforme 8051 hanno solo 128 byte di SRAM utente).

Non ha senso supportare l'allocazione dinamica della memoria con una quantità così piccola di RAM. (nuovo / cancella) o anche malloc in C.

Uno dei principali miglioramenti da C a C ++ è il paradigma orientato agli oggetti. C ++ è adatto a software con un ingombro di memoria maggiore

ma non nel firmware incorporato con limitazione delle dimensioni fino a 32 KB. (ad esempio in una placca MCU a 16 bit)

Non è necessario avere un compilatore C ++ che è generalmente più complicato del compilatore C. (almeno i provider di SDK non si preoccuperanno di farlo).

In effetti, non riesco a trovare un compilatore C ++ su una piattaforma ARM7 a 32 bit.

Non vale la pena la complessità

In alcuni 8051 (8 bit): 1 MB di ROM, 128B di RAM

TI MSP430 (16 bit): 32 KB di ROM, 4 KB di RAM

ST Microelectronics ARM Cortex ™ -M3 CPU Core a 32 bit (STM32F103T4): 16 o 32 Kbyte di memoria Flash 6 o 10 Kbyte di SRAM

    
risposta data 09.07.2014 - 11:26
fonte
-4

Vedo un paio di possibili motivi:

  • C è un po 'più efficiente se confrontato con l'equivalente in C ++.
  • Alcune librerie che usano sono scritte in C
  • Usano alcune parti del kernel di Linux, che è scritto in C.

A cura: Come risulta, il terzo argomento non è vero (vedi commenti).

    
risposta data 10.12.2012 - 18:53
fonte
-4

Perché C è probabilmente una lingua migliore di C ++. E poiché parte del codice è stata scritta prima che il C ++ diventasse popolare e le persone non avessero avuto un motivo per sostituirlo.

E poiché C ++ ha molte funzionalità che possono infrangere il tuo codice se non stai attento quando lo usi in un kernel.

    
risposta data 10.12.2012 - 18:46
fonte

Leggi altre domande sui tag