2010-04-03 10 views
43

Mi scuso se si tratta di una domanda soggettiva o ripetuta. È una specie di imbarazzante ricerca, quindi non ero sicuro di quali termini includere.Cosa puoi fare in C senza "std" include? Fanno parte di "C" o solo delle biblioteche?

Quello che mi piacerebbe sapere è quali sono gli strumenti/le funzioni di base in C quando non si includono librerie standard come stdio e stdlib.

Cosa posso fare se non c'è printf(), fopen(), ecc.?

Inoltre, queste librerie sono tecnicamente parte della lingua "C" o sono solo librerie molto utili ed effettivamente essenziali?

+5

+ 1 per la domanda interessante – fmsf

risposta

26

Lo standard C ha questo da dire (5.1.2.3/5):

dei minimi requisiti su conforme attuazione sono:

- Nei punti di sequenza, oggetti volatili sono stabili il senso che gli accessi precedenti a sono completi e gli accessi successivi a non si sono ancora verificati.

- A conclusione del programma, tutti i dati scritti in file devono essere identici al risultato che l'esecuzione del programma secondo le astratte semantica avrebbe prodotto.

- La dinamica di ingresso e uscita dispositivi interattivi avvengono come specificato 7.19.3.

Quindi, senza le funzioni di libreria standard, l'unico comportamento garantito da un programma è relativo ai valori degli oggetti volatili, poiché non è possibile utilizzare alcuno dei file di accesso garantiti o "dispositivi interattivi" . "Pure C" fornisce solo l'interazione tramite le funzioni di libreria standard.

Pure C non è l'intera storia, tuttavia, dal momento che l'hardware può avere determinati indirizzi che eseguono determinate operazioni quando vengono letti o scritti (che si tratti di un bus SATA o PCI, memoria video raw, una porta seriale, qualcosa da emette un segnale acustico o un LED lampeggiante). Quindi, sapendo qualcosa sul tuo hardware, puoi scrivere un intero lotto in C senza utilizzare le funzioni di libreria standard. Potenzialmente, è possibile implementare la libreria standard C, anche se ciò potrebbe richiedere l'accesso a speciali istruzioni della CPU e speciali indirizzi di memoria.

Ma in C pura, senza estensioni e le funzioni della libreria standard rimosse, in pratica non si può fare altro che leggere gli argomenti della riga di comando, fare un po 'di lavoro e restituire un codice di stato da main. Questo non deve essere annusato, è ancora Turing completo soggetto a limiti di risorse, sebbene la tua unica risorsa siano variabili automatiche e statiche, nessuna allocazione di heap. Non è un ambiente di programmazione molto ricco.

Le librerie standard fanno parte delle specifiche del linguaggio C, ma in qualsiasi lingua tende ad essere una linea tracciata tra la lingua "come tale" e le librerie. È una differenza concettuale, ma alla fine non è molto importante in linea di principio, perché lo standard dice che si uniscono. Chiunque stia facendo qualcosa di non standard potrebbe rimuovere facilmente le caratteristiche della lingua come librerie. In entrambi i casi, il risultato non è un'implementazione conforme di C.

Si noti che un'implementazione "indipendente" di C deve solo implementare un sottoinsieme di standard include non incluso alcuno dell'I/O, quindi ci si trova nel posizione che ho descritto sopra, basata su estensioni specifiche dell'hardware per fare qualcosa di interessante. Se vuoi fare una distinzione tra il "linguaggio principale" e "le librerie" basato sullo standard, allora quello potrebbe essere un buon posto per tracciare la linea.

+1

Grazie. Ottima spiegazione. –

2

Non si può fare molto, poiché la maggior parte delle funzioni di libreria standard si basano su chiamate di sistema; sei limitato a ciò che puoi fare con le parole chiave e gli operatori C incorporati. Dipende anche dal sistema; in alcuni sistemi potresti essere in grado di manipolare i bit in un modo che risulta in alcune funzionalità esterne, ma è probabile che sia l'eccezione piuttosto che la regola.

L'eleganza di C è nella sua semplicità, tuttavia. A differenza di Fortran, che include molte funzionalità come parte del linguaggio, C è piuttosto dipendente dalla sua libreria. Ciò gli conferisce un alto grado di flessibilità, a scapito di essere un po 'meno coerente da una piattaforma all'altra.

Questo funziona bene, ad esempio, nel sistema operativo, dove sono implementate "librerie" completamente separate, per fornire funzionalità simili con un'implementazione all'interno del kernel stesso.

Alcune parti delle librerie sono specificate come parte di ANSI C; sono parte del linguaggio, suppongo, ma non al centro.

2

Nessuno di essi fa parte delle parole chiave della lingua. Tuttavia, tutte le distribuzioni C devono includere un'implementazione di queste librerie. Ciò garantisce la portabilità di molti programmi.

Prima di tutto, potresti teoricamente implementare tutte queste funzioni da solo utilizzando una combinazione di C e assemblaggio, in modo da poter teoricamente fare qualsiasi cosa.

In termini pratici, le funzioni di libreria sono pensate principalmente per salvarvi il lavoro di reinventare la ruota. Alcune cose (come le funzioni di stringa e libreria) sono più facili da implementare. Altre cose (come I/O) dipendono molto dal sistema operativo. Scrivere la propria versione sarebbe possibile per un O/S, ma renderà il programma meno portabile.

Ma potresti scrivere programmi che fanno un sacco di cose utili (ad es. Calcolare PI o il significato della vita o simulare un automa). A meno che non si utilizzi direttamente il sistema operativo per I/O, tuttavia, sarebbe molto difficile osservare quale sia l'output.

Nella programmazione quotidiana, il successo di un linguaggio di programmazione richiede in genere la disponibilità di un'utile libreria standard e librerie di alta qualità per molte attività utili. Questi possono essere di prima parte o di terze parti, ma devono essere lì.

13

Cosa potresti fare? Qualunque cosa!

Non c'è magia in C, tranne forse il preprocessore.

Il più difficile, forse è scrivere putchar, poiché è un I/O dipendente dalla piattaforma.

È un buon esercizio per la creazione di una versione personalizzata di vararg e, una volta ottenuto ciò, eseguire la propria versione di vaprintf, quindi printf e sprintf.

Ho fatto tutto su un Macintosh nel 1986 quando non ero soddisfatto delle routine di stdio fornite con Lightspeed C - scriveva il mio gestore di finestre con win_putchar, win_printf, in_getchar e win_scanf.

Questo intero processo si chiama bootstrap e può essere una delle esperienze più gratificanti nella codifica: lavorare con un design di base che dia una buona dose di senso pratico.

+1

Sì, e non è possibile scrivere putchar in C. – WhirlWind

+0

write (3) è il primo syscall di cui hai bisogno :) @whirlwind int win_putchar (char c) {return write (1, &c, 1);} – dzen

+0

Spiacente, scrivi (3) non è un syscall, è una funzione standard di libray. Sys_write è la chiamata di sistema nella maggior parte dei casi, e buona fortuna chiamarla direttamente senza assembly o la funzione di libreria syscall() – WhirlWind

2

Le librerie std sono librerie "standard", in quanto per un compilatore C deve essere conforme a uno standard (ad esempio C99), queste librerie devono essere "inclusibili". Per un esempio interessante che potrebbe aiutare nella comprensione di ciò che questo significa, dare un'occhiata alla sfida di Jessica McKellar qui:

http://blog.ksplice.com/2010/03/libc-free-world/

0

La CRT è parte del linguaggio C tanto quanto le parole chiave e la sintassi. Se stai usando C, il tuo compilatore DEVE fornire un'implementazione per la tua piattaforma di destinazione.

Modifica: È lo stesso di STL per C++. Tutte le lingue hanno una libreria standard. Forse assemblatore come eccezione o altri linguaggi di livello molto basso. Ma la maggior parte dei livelli medio/alti ha librerie standard.

+2

Si potrebbe voler vedere la differenza tra un'implementazione "ospitata" (che richiede la libreria standard completa) e un'implementazione "indipendente", che richiede solo poche librerie. –

0

La libreria standard C fa parte di ANSI C89/ISO C90. Recentemente ho lavorato alla libreria per un compilatore C che in precedenza non era conforme ANSI.

Il libro The Standard C Library di P.J. Plauger è stato un ottimo riferimento per questo progetto. Oltre a precisare i requisiti dello standard, Plauger spiega la storia di ciascun file .h e le ragioni alla base di alcuni dei progetti API. Fornisce anche una piena implementazione della libreria, qualcosa che mi ha aiutato molto quando qualcosa nello standard non era chiaro.

Lo standard descrive le macro, i tipi e le funzioni per ciascuno dei 15 file di intestazione (include stdio.h, stdlib.h, ma anche float.h, limits.h, math.h, locale.h e altro).

Un compilatore non può pretendere di essere ANSI C a meno che non includa la libreria standard.

+0

Potrebbe essere un'implementazione indipendente senza la libreria (solo le intestazioni di macro) - non può essere un'implementazione host, tuttavia, senza la libreria. –

+0

@ Jonathan: corretto, spiega dove la libreria deve interfacciarsi con l'host (stdio, segnali, uscita, ecc.). Gran parte della libreria standard è indipendente dalla piattaforma host, ma ci sono parti di esso che richiedono un'interfaccia all'host. – tomlogic

+0

Un compilatore non è una libreria. Può compilare lo standard C, oppure no. Sebbene sia bello avere una libreria C standard con un compilatore, non è un requisito in nessuna direzione. –

6

Non sei certamente obbligato a utilizzare le librerie standard se non ne hai bisogno. Parecchi sistemi integrati non hanno supporto per le librerie standard o non possono usarli per un motivo o per un altro. La norma parla anche specificamente implementazioni senza supporto di libreria standard C99 5.1.2.1 "ambiente autoportante":

In un ambiente indipendente (in cui l'esecuzione del programma C può avvenire senza alcun beneficio di un sistema operativo), il nome e il tipo della funzione chiamata all'avvio del programma sono definiti dall'implementazione. Qualsiasi struttura di libreria disponibile per un programma indipendente, oltre al set minimo richiesto dalla clausola 4, è definita dall'implementazione.

Le intestazioni richieste da C99 per essere disponibile in un'implemenation freestanding sono <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h> e <stdint.h>. Queste intestazioni definiscono solo tipi e macro, quindi non è necessario che una libreria di funzioni li supporti.

Senza la libreria standard, sei totalmente dipendente dal tuo codice, da tutte le librerie non standard che potrebbero essere disponibili e da tutte le chiamate di sistema del sistema operativo che potresti essere in grado di interfacciare (che potrebbero essere considerate chiamate di libreria non standard).Molto probabilmente dovresti avere le routine di assemblaggio delle chiamate del programma C per interfacciare i dispositivi e/o qualsiasi altro sistema operativo sulla piattaforma.

-2

Il linguaggio assembly ha comandi semplici che spostano i valori ai registri della CPU, della memoria e di altre funzioni di base, oltre a eseguire le funzionalità di base e i calcoli della macchina. Le librerie C sono fondamentalmente blocchi di codice assembly. Puoi anche usare il codice assembly nei tuoi programmi C. var è un'istruzione di codice assembly. Quando si utilizza 0x prima di un numero per renderlo esadecimale, si tratta di istruzioni di assemblaggio. Il codice assembly è la forma leggibile del codice macchina, che è la forma visiva degli stati effettivi degli switch dei percorsi dei circuiti.

Così mentre il codice macchina, e quindi il codice assembly, è incorporato nella macchina, i linguaggi C sono combinati con tutti i tipi di combinazioni preformate di codice, incluse le proprie funzioni che potrebbero essere in linguaggio assembly parziale e in parte chiamata su altre funzioni del linguaggio assembly o altre librerie C. Quindi il codice assembly è il fondamento di tutta la programmazione, dopodiché è il caso di chiunque a indovinare cosa sia. Ecco perché ci sono così tante lingue e così pochi veri standard.

5

Cosa posso fare se non c'è printf(), fopen(), ecc.?

Finché si sa come interfacciare il sistema che si sta utilizzando è possibile vivere senza la libreria C standard. Nei sistemi embedded in cui si hanno solo diversi kilobyte di memoria, probabilmente non si vuole usare la libreria standard.

Ecco un mondo Hello! esempio su Linux e Windows senza l'utilizzo di funzioni C standard:

Per esempio su Linux è possibile richiamare il sistema Linux chiama direttamente in assembly inline:

/* 64 bit linux. */ 

#define SYSCALL_EXIT 60 
#define SYSCALL_WRITE 1 

void sys_exit(int error_code) 
{ 
    asm volatile 
    (
     "syscall" 
     : 
     : "a"(SYSCALL_EXIT), "D"(error_code) 
     : "rcx", "r11", "memory" 
    ); 
} 

int sys_write(unsigned fd, const char *buf, unsigned count) 
{ 
    unsigned ret; 

    asm volatile 
    (
     "syscall" 
     : "=a"(ret) 
     : "a"(SYSCALL_WRITE), "D"(fd), "S"(buf), "d"(count) 
     : "rcx", "r11", "memory" 
    ); 

    return ret; 
} 

int _start() 
{ 
    const char hwText[] = "Hello world!\n"; 

    sys_write(1, hwText, sizeof(hwText)); 
    sys_exit(12); 

    return 0; 
} 

compilare questo con:

gcc -nostdlib nostd.c 

E emette Hello world! ed esce.

Su Windows le chiamate di sistema non vengono pubblicate, ma sono nascoste dietro un altro livello di astrazione, il kernel32.dll. Che viene sempre caricato all'avvio del programma, che lo si voglia o no. Così si può semplicemente includere windows.h e utilizzare l'API Win32:

#include <windows.h> 

int _start() 
{ 
    const char str[] = "Hello world!\n"; 
    HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); 
    DWORD written; 

    WriteFile(stdout, str, sizeof(str), &written, NULL); 
    ExitProcess(12); 

    return 0; 
} 

Il windows.h non ha nulla a che fare con la libreria standard C, come si dovrebbe essere in grado di scrivere i programmi di Windows su qualsiasi altra lingua troppo.

È possibile compilare utilizzando gli strumenti MinGW in questo modo:

gcc -nostdlib C:\Windows\System32\kernel32.dll nostdlib.c 

Poi il compilatore è abbastanza intelligente per risolvere le dipendenze di importazione e compilare il programma.

Se si disassembla il programma, è possibile vedere solo il proprio codice, non c'è nessuna libreria standard gonfia.

Quindi è possibile utilizzare C senza la libreria standard.