2010-02-19 7 views
9

C'è qualche differenza in C che è scritta in Windows e Unix?
Insegno sia in C che in C++ ma alcuni dei miei studenti sono tornati dicendo che alcuni dei programmi di esempio non vengono eseguiti per loro in Unix. Unix è estraneo a me. Purtroppo nessuna esperienza con esso. Tutto quello che so è scriverlo. Se ci sono delle differenze, dovrei consigliare al nostro dipartimento di investire sui sistemi per Unix poiché al momento non ci sono sistemi Unix nel nostro laboratorio. Non voglio che i miei studenti sentano di essere stati negati o tenuti lontani da qualcosa.Differenze tra piattaforme del programma C su Windows e Unix OS

+2

Forse stai facendo delle ipotesi che non sono garantite come vere secondo lo standard C, ma sono vere in un ambiente Windows. Se puoi, per favore pubblica un piccolo programma che mostri questo comportamento. Dovresti anche leggere lo standard C, o la versione draft se non puoi permetterti di comprarlo: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf (questo è per C99). –

+5

Nessun sistema UNIX nel tuo laboratorio? Wow. Quanto sarebbe difficile creare un paio di Linux box? –

+0

Un semplice esempio è '#include '. Quel file non esiste in Unix. Ci sono troppe differenze e un elenco esaustivo potrebbe non essere comunque possibile. –

risposta

15

Questo tipo di problemi di solito appaiono quando non si attaccano allo standard C nuda, e fare ipotesi circa l'ambiente che potrebbe non essere vero. Questi possono includere dipendenza:

  • non standard, specifica piattaforma include (<conio.h>, <windows.h>, <unistd.h>, ...);
  • comportamento non definito (fflush(stdin), come è stato segnalato da qualcun altro, non è richiesto di fare nulla dallo standard - è in realtà un comportamento indefinito invocare fflush su qualsiasi cosa tranne i flussi di output; in generale, i compilatori più vecchi erano più indulgenti in merito alla violazione di alcune regole sottili come il rigoroso aliasing, quindi fai attenzione con i trucchi puntatori "intelligenti");
  • tipo di dati di formato (il bit short = 16, int = long = 32 assunzione bit non tenere ovunque - 64 bit Linux, per esempio, ha 64 bit long);
  • in particolare, dimensioni del puntatore (void * non è sempre a 32 bit, e non può essere sempre fusa in modo sicuro ad una unsigned long); in generale, si dovrebbe stare attenti con conversioni e confronti che coinvolgono puntatori, e si dovrebbe sempre utilizzare i tipi previsti per quel tipo di attività, invece di "normali" int s (si veda in particolare size_t, ptrdiff_t, uintptr_t) Tipo
  • dati " formato interno "(lo standard non dice che float se double s siano in IEEE 754, sebbene non abbia mai visto le piattaforme farlo in modo diverso);
  • funzioni non standard (__beginthread, MS stringhe sicure funzioni, dall'altro lato, le estensioni POSIX/GNU)
  • estensioni del compilatore (__inline, __declspec, #pragma s, ...) e, in generale, tutto ciò che inizia con la doppia sottolineatura (o anche con un trattino singolo, in implementazioni vecchie e non standard);
  • codici di escape della console (questo di solito è un problema quando si tenta di eseguire il codice Unix su Windows);
  • formato di ritorno a capo: in stringhe normali è \n ovunque, ma se scritto su file è \n su * NIX, \r\n su Windows, \r su Mac pre-OSX; la conversione viene gestita automagicamente dai flussi di file, quindi fate attenzione di aprire i file in formato binario quando effettivamente vuole scrivere dati binari, e lasciarli in modalità testo quando si desidera scrivere il testo.

In ogni caso un esempio di programma che non si compila su * NIX sarebbe utile, potremmo darvi suggerimenti più precisi.

I dettagli sul programma sono ancora da ottenere. Gli studenti provenivano dal nostro gruppo precedente. L'ho chiesto. turbo C è ciò che viene attualmente utilizzato.

Come detto nel commento, si prega di cadere Turbo C e (se lo si utilizza) Turbo C++, al giorno d'oggi sono entrambi pezzi di storia e hanno molte incompatibilità con gli standard C++ C attuale e (e se ricordo bene entrambi generano file eseguibili a 16 bit, che non funzioneranno nemmeno su sistemi operativi a 64 bit su x86_64).

Esistono molte alternative gratuite, di lavoro e conformi agli standard (VC++ Express, MinGW, Pelles C, CygWin su Windows e gcc/g ++ è lo standard di fatto su Linux, rivaleggiato da clang), solo devo sceglierne uno

+1

+1 per CygWin e gcc/g ++ su Windows. Ti permetteranno di scrivere standard c che si compilerà praticamente su qualsiasi * nix e Mac osX. IMO è la strada da percorrere. –

+0

Il problema con loro è che CygWin ha bisogno del suo runtime, dopotutto è un livello di compatibilità UNIX, quindi non lo consiglierei per i progetti nativi. MinGW, dall'altra parte, emette EXE Windows "normali" nativi. Tuttavia, almeno quando l'ho provato, sembrava ottimizzare peggio di VC++ e di gcc/g ++ su Linux, e non può usare il "normale" Platform SDK di Microsoft, e non mi piace troppo. Quindi, io uso VC++ su Windows e g ++/gcc su Linux; è anche utile compilare la tua applicazione con due compilatori diversi, tieni immediatamente i problemi che ho descritto sopra. –

+0

In realtà, cygwin ti permette di produrre file eseguibili senza bisogno di una libreria cygwin, in modo che il commento non sia davvero terribilmente valido. (Dalla memoria, è il -mingw, -msys o -mno-cygwin o qualche altra opzione lungo quelle linee). Hai ragione, comunque, che gcc non produce necessariamente risultati ottimali come altri compilatori - gcc, comunque, pesantemente trasferito su molte architetture e piattaforme, il che è un vantaggio sostanziale. – Arafangion

1

Non deve esserci differenza tra il linguaggio di programmazione C sotto Windows o * nix, poiché la lingua è specificata dallo standard ISO.

2

La sintassi C deve essere la stessa se entrambi i compilatori Windows e Unix aderiscono allo stesso standard C. Mi è stato detto che i compilatori MS ancora non supportano C99 in pieno, anche se i compilatori Unix sono alla velocità, quindi sembra che C89 sia un minimo comune denominatore.

Tuttavia nel mondo Unix in genere si utilizzerà POSIX chiamate di sistema per fare cose del sistema, come IPC ecc Windows non è sistema POSIX così ha API diverso per esso.

10

La lingua è la stessa, ma le librerie utilizzate per ottenere qualcosa di specifico per piattaforma sono diverse. Ma se stai insegnando C (e non la programmazione dei sistemi) dovresti essere in grado di scrivere codice portatile. Il fatto che tu non lo stia facendo mi fa meravigliare della qualità dei tuoi materiali di formazione.

0

Un problema comune è che fflush(stdin) non funziona su Unix. Che è perfettamente normale, poiché lo standard non definisce come l'implementazione dovrebbe gestirlo. La soluzione è quella di utilizzare qualcosa di simile (non testata):

do 
{ 
    int c = getchar(); 
} 
while (c != '\n' && c != EOF); 

Allo stesso modo, è necessario evitare tutto ciò che provoca un comportamento indefinito.

1

Il linguaggio C è di per sé portatile da Windows a Unix. Ma i dettagli del sistema operativo sono diversi e a volte quelli invadono il tuo codice.

per i sistemi UNIX esempio utilizzano in genere solo "\ n" per separare le righe in un file di testo, mentre la maggior parte strumenti di Windows si aspettano di vedere "\ r \ n". Ci sono modi per affrontare questo tipo di differenza in un modo che possa essere gestito dal runtime di C per te, ma se non fai attenzione a conoscerli, è piuttosto semplice scrivere codice C specifico per il sistema operativo.

ho potuto che si esegue un Unix in una Macchina Virtuale e l'uso che per testare il codice prima di condividere con i tuoi studenti.

1

Penso che sia fondamentale che tu familiarizzi con unix in questo momento.

Un ottimo modo per fare questo è una con un CD Knoppix.

Prova a compilare i tuoi programmi su Linux usando gc, e quando non funzionano, rintraccia i problemi (#include <windows>?) E fallo funzionare. Quindi tornare a Windows, e sarà probabilmente compilare ok.

In questo modo, scoprirete che i vostri programmi diventano più puliti e un materiale didattico migliore, anche per esercitazioni in laboratorio su macchine Windows.

4

Le librerie standard fornite con MSVC e quelle fornite con un tipico compilatore Linux o Unix sono abbastanza diverse da poter riscontrare problemi di compatibilità. Potrebbero esserci anche variazioni dialettiche minori tra MSVC e GCC.

Il modo più semplice per testare gli esempi in un ambiente unix è installare Cygwin o MSYS sul kit Windows esistente. Questi sono basati su GCC e comuni librerie open-source e si comportano molto più come l'ambiente del compilatore C su un sistema unix o linux.

  • Cygwin è il 'unix come' più, e si basa su un cygwin.dll, che è un livello di emulazione che emula sistema Unix chiamate in cima alla API Win32 nativo. Generalmente qualsiasi cosa possa essere compilata su Cygwin è molto probabile che venga compilata su Linux, poiché Cygwin è basato su gcc e glibc. Tuttavia, le API native Win32 non sono disponibili per le applicazioni compilate su Cygwin.

  • MSYS/MinGW32 è progettato per la produzione di app native Win32 tramite GCC. Tuttavia, la maggior parte delle librerie GNU standard e altre librerie OSS sono disponibili, quindi si comporta più come un ambiente unix rispetto a VC. In effetti, se si sta lavorando con codice che non utilizza API Win32 o Unix specifiche, probabilmente eseguirà il porting tra MinGW32 e Linux più facilmente di quanto avverrebbe tra MinGW32 e MSVC.

mentre ottenere Linux installato nel vostro laboratorio è probabilmente una cosa utile da fare (lettore utilizzare VMware o qualche altro hypervisor se non è possibile ottenere finanziamenti per nuovi server) è possibile utilizzare uno dei toolchain di cui sopra per ottenere qualcosa che probabilmente sarà "abbastanza vicino" ai tuoi scopi. Puoi imparare Unix come vuoi, e sia Cygwin che MSYS ti offriranno un ambiente simile a unix che potrebbe darti un'introduzione gentile nel frattempo.

2

C'è questa cosa chiamata Ansi C. Finché si codifica semplicemente Ansi C, non ci dovrebbero essere differenze. Tuttavia, questa è un'ipotesi piuttosto accademica.

Nella vita reale, non ho mai visto nessuno dei miei codici portatile da Linux a Windows e viceversa senza alcuna modifica. In realtà, questa modifica S (decisamente plurale) si è rivelata una vasta gamma di direttive di pre-elaborazione, come #ifdef WINDOWS ... #endif e #ifdef UNIX ... #endif ... anche di più, se sono state utilizzate alcune librerie parallele, come OPENMPI.

Come si può immaginare, questo è totalmente in contrasto con il codice leggibile e debugable, ma che è stato ciò che ha funzionato ;-)

Inoltre, avete avuto modo di considerare le cose già menzionati: UTF-8 a volte mettere fuori linux compilatori ...

Problemi correlati