2009-11-16 18 views
15

Sono abituato al vecchio stile C e recentemente ho iniziato a esplorare le funzionalità del c99. Ho solo una domanda: il mio programma verrà compilato correttamente se uso c99 nel mio programma, il flag c99 con gcc e lo collego con le librerie c99 precedenti?C99 è retrocompatibile con C89?

Quindi, devo attenermi alla vecchia C89 o evolvere?

+0

grazie a tutte le risposte. Vedo i professionisti più dei contro qui, quindi comprimere gli oggetti e passare al c99 ora: p – kar

risposta

9

Credo che siano compatibili a tale riguardo. Questo è finchè le cose che stai compilando contro non calpestano nessuna delle nuove chicche. Ad esempio, se il vecchio codice contiene , allora sei nei guai. Come un dinosauro simile, sto lentamente abbracciando il meraviglioso nuovo mondo di C99. Dopotutto, è rimasto là fuori in agguato da circa 10 anni;)

+8

In realtà, finché non includi '', sei libero di usare l'identificativo 'bool' nel codice C99. C99 definisce le parole chiave '_Bool',' _True' e '_False' come parte della lingua, e l'intestazione' 'le alias su' bool', 'true' e' false'. –

+1

Tecnicamente, il tipo di ritorno implicito 'int' è permesso in C89 ma non in C99, ma se il tuo codice usa ancora quelli allora hai problemi molto più grandi e dovresti passare a C99 solo per pulirli. (Si noti che potrebbero esserci altri problemi C89/C99 lungo queste linee, ma rientrano tutti nella stessa categoria più o meno.) –

+0

AFAIK, true e false sono definiti su 1 e 0. _True e _False non esistono. – marcus

1

È progettato per essere compatibile con le versioni precedenti. Formatta le estensioni che molti fornitori hanno già implementato. È possibile, forse anche probabile, che un programma ben scritto non abbia problemi durante la compilazione con C99.

Nella mia esperienza, la ricompilazione di alcuni moduli e non di altri per risparmiare tempo ... spreca un sacco di tempo. Di solito ci sono alcuni dettagli facilmente trascurati che hanno bisogno del nuovo compilatore per renderlo compatibile.

2

Rispettoso: Provalo e scoprilo. :-)

Tuttavia, tieni presente che anche se è necessario correggere alcune differenze di compilazione di minior, è probabile che il passaggio sia più importante.

2

Se non si violano le caratteristiche C99 esplicite, un codice c90 funzionerà con flag c99 con altre precedenti librerie c99.

Ma ci sono alcune librerie basate su dos in C89 come ,, che sicuramente non funzioneranno.

C99 è molto flessibile quindi sentitevi liberi di migrare :-)

2

Le convenzioni di chiamata tra le librerie C non è cambiata nei secoli, e in effetti, io non sono sicuro che abbia mai fatto.

I sistemi operativi a questo punto si basano molto sulle convenzioni di chiamata C poiché le API C tendono ad essere la colla tra i pezzi del sistema operativo.

Quindi, in pratica la risposta è "Sì, i file binari saranno compatibili con le versioni precedenti. No, naturalmente, il codice che utilizza le funzionalità di C99 non può essere compilato in un secondo momento con un compilatore non C99."

7

Si dovrebbe evolvere. Grazie per l'ascolto :-)

In realtà, mi dilungherò su quello.

Hai ragione che C99 è in circolazione da un po 'di tempo. È (a mio parere) utilizzare lo standard per qualsiasi altro che non sia il codice legacy (in cui è sufficiente correggere i bug piuttosto che aggiungere nuove funzionalità). Probabilmente non ne vale la pena per il codice legacy ma dovresti (come con tutte le decisioni aziendali) fare la tua analisi costi/benefici.

Sto già assicurando che il mio nuovo codice sia compatibile con C1x - mentre non sto ancora utilizzando nessuna delle nuove funzionalità, cerco di assicurarmi che non si rompa.

Per quanto riguarda il codice da osservare, gli autori degli standard prendono seriamente la compatibilità con le versioni precedenti .Il loro compito non era mai quello di progettare una nuova lingua, era codificare le pratiche esistenti.

La fase in cui si trovano in questo momento consente loro un po 'più di libertà nell'aggiornamento della lingua, ma seguono ancora il giuramento di Ippocrate in termini di risultati: "prima di tutto, non fare del male".

In genere, se il codice è rotto con un nuovo standard, il compilatore è costretto a dirtelo. Quindi compilare semplicemente la base di codice sarà un ottimo inizio. Tuttavia, se leggi lo C99 rationale document, vedrai apparire la frase "modifica silenziosa": è questo che devi fare attenzione.

Queste sono modifiche comportamentali nel compilatore di cui non è necessario essere informati e possono essere fonte di molta angoscia e digrignamento di denti se l'applicazione inizia a comportarsi in modo strano. Non preoccuparti del bit "quiet change in c89" - se fossero un problerm, sarebbe già stato morso da loro.

Questo documento, a proposito, è un'ottima lettura per capire perché lo standard attuale dice ciò che dice.

+0

Hai un puntatore a quali novità arriveranno in C1x? Sembra che i TRs "sicuri" non vengano incorporati (almeno non sembrano essere nella bozza del marzo 2009). Preferirei non dover leggere tutta la bozza del documento per cercare di individuare le novità. –

+0

Sto usando n1362 (bozza di marzo). Le cose possono essere tirate fuori fino al momento in cui lo standard è ufficialmente votato (anche se, naturalmente, diventa meno probabile quando si avvicina il voto). Nonostante il fatto che penso che le funzioni "sicure" siano una stampella per le persone che non hanno codifica di business in C, in primo luogo :-), mi sto ancora comportando come se fossero lì, dal momento che il WG14 sta ancora lavorando a loro come a maggio '09 (anche se mi accorgo che ora li chiamano "interfacce di controllo dei limiti" più appropriate - non erano mai * sicuri *). Non li sto usando, solo per assicurarmi che * il mio * codice non sia rotto da loro. – paxdiablo

+0

In realtà, non odio più di tanto le funzioni limitate dal momento che riducono lo sforzo. Ho solo odiato il fatto che fossero chiamati al sicuro. Sono sicuri solo se li usi correttamente e questo è vero per tutte le funzioni di C *. – paxdiablo

1

Alcune caratteristiche C89 non sono validi C99

Probabilmente, esistono quelle caratteristiche solo per ragioni storiche, e non deve essere utilizzato nel codice C89 moderna, ma esistono.

The C99 N1256 standard draft prefazione paragrafo 5 confronta C99 a revisioni precedenti, ed è un buon punto di partenza per cercare quelle incompatibilità, anche se ha di gran lunga più estensioni di restrizioni.

implicito ritorno int e tipi di variabili

citati di Lutz in un commento, ad esempio i seguenti sono C89 valida:

static i; 
f() { return 1; } 

ma non C99, in cui si deve scrivere:

static int i; 
int f() { return 1; } 

Questo preclude anche funzioni senza prototipi chiamando in C99: Are prototypes required for all functions in C89, C90 or C99?

n1256 dice:

rimuovere implicit int

ritorno senza espressione per la funzione non vuoto

valido C89, C99 non valida:

int f() { return; } 

Penso che in C89 che restituisce un valore di implementazione definito.n1256 dice:

ritorno senza espressione non consentita in funzione che restituisce un valore

Divisione intera all'operando negativo

  • C89: giri ad una direzione di attuazione definite
  • C99: round a 0

Quindi, se il compilatore è stato arrotondato a -inf e si è basato su tale comportamento definito dall'implementazione, il compilatore è ora costretto a violare il codice su C99.

https://stackoverflow.com/a/3604984/895245

n1256 dice:

intero affidabile divisione

compatibilità con Windows

Una delle principali preoccupazioni pratica è essere in grado di compilare in Windows, dal momento che Microsoft does not intend to implement C99 fully too soon .

Questo è ad esempio il motivo per cui libgit2 limits allowed C99 features.

+0

Una differenza più significativa è che in C89, la definizione di indirizzo e di operatori di riferimento indiretto implica che se v è un lvalue di tipo 'T', quindi dopo' T * p = & v', i lvalues ​​'v' e '* p' sarà equivalente nel loro stato di vita a meno che' p' non venga sovrascritto, e questo principio si applica anche se 'v' era un membro del sindacato. Scrivere un membro del sindacato come un tipo e leggere come un altro sarebbe definito in alcuni casi (ad esempio, la garanzia della sequenza iniziale comune) e in altri casi sarebbe definito dall'implementazione, il che significa che le implementazioni dovevano specificare se aliasing tra i puntatori (piuttosto che tra ... – supercat

+0

... un puntatore e un lvalue a accesso diretto) farebbero qualcosa di diverso dai dati reinterpretati bytewise. C99 modifica tali regole in modi che rendono essenzialmente impossibile adattare il codice che avrebbe avuto un comportamento ben definito sulla maggior parte dei compilatori C89, e potrebbe eseguire il test in fase di compilazione per caratteristiche insolite che potrebbero infrangerlo. – supercat

+0

@supercat grazie per la spiegazione. Aggiungi un esempio di codice minimale con una spiegazione di differenza di comportamento C89 vs C99 da una sola linea :-) –

1

Ci sono alcune parti dello standard C89 che sono scritte ambiguamente e, a seconda di come si interpreta la regola sui tipi di puntatori e gli oggetti a cui stanno accedendo, lo standard può essere visto come descrivendo uno tra due molto diversi linguaggi - uno dei quali semanticamente molto più potente e di conseguenza utilizzabile in una gamma più ampia di campi, e uno dei quali consente maggiori opportunità per l'ottimizzazione basata sul compilatore. Lo standard C99 "ha chiarito" la regola per chiarire che non fa alcuno sforzo per imporre la compatibilità con la lingua precedente, anche se è stata favorita in modo schiacciante in molti campi; considera anche indefinite alcune cose che sono state definite in C89 ma solo perché le regole C89 non sono state scritte con una precisione tale da impedirne l'uso (ad esempio l'uso di memcpy per la punteggiatura di tipo nei casi in cui la destinazione abbia durata heap).

C99 può quindi essere compatibile con il linguaggio che i suoi autori pensavano fosse descritto da C89, ma non è compatibile con la lingua che è stata elaborata dalla maggior parte dei compilatori C89 negli anni '90.

Problemi correlati