Perché C ha bisogno della parola chiave “struct” e non del C ++?

Sono sempre stato un po ‘confuso su quello che sta succedendo qui:

#include  int main() { timeval tv; tv.tv_sec = 1; for (;;) { select(0, 0, 0, 0, &tv); printf("%s\n", "Hello World!"); } } 

Scusa se questo non viene compilato, è sufficiente scriverlo come un rapido esempio.

Codice come questo non verrà compilato sotto gcc a meno che non aggiunga la struct della parola chiave prima dell’uso della struct timeval. g ++ d’altra parte lo maneggia bene così com’è.

Questa è una differenza tra come C e C ++ gestiscono le strutture o è solo una differenza nei compilatori? (Sono molto orientato al C ++, e l’uso della struct in C su righe come questa mi ha sempre un po ‘sconcertato).

Sintatticamente entrambi trattano la struct quasi allo stesso modo. Solo C ++ ha aggiunto una regola aggiuntiva che consente di omettere la parola chiave struct (e class ) se non c’è ambiguità.

Se c’è ambiguità, anche C ++ richiede la parola chiave struct in alcuni punti. Un esempio famoso è stat sui sistemi POSIX in cui è presente una struct stat e una funzione stat .

Direi che è una decisione di design di entrambe le lingue.

Le strutture in C sono solo record strutturati e hanno un utilizzo diverso dal tipo built-in.

C ++ ha dei cori e sovraccarichi dell’operatore e quindi agiscono come tipi.

 struct foo x; // create a structure of pattern foo typedef foo foo_type; // "define" a type foo_type x; // create an instance of type foo_type 

C ++:

 foo x; // create an instance of type foo 

Come nota a struct foo , struct foo è ancora permesso in C ++. struct foo è più semplice da analizzare, quindi typedef’d foo come la ricerca del nome è più semplice.

Considera l’idea originale di C ++ (o, quando era solo un’idea, “C with classs”), quella di un linguaggio orientato all’OO che era compatibile con C al punto in cui i programmi C più validi erano anche programmi C ++ validi.

C ++ ha costruito il suo modello di class iniziando con la struct di C e aggiungendo qualche ulteriore funzionalità:

  1. Ereditarietà (anche se puoi avvicinarti in C con il primo membro di una struct, la struct che vuoi “ereditare” da).
  2. Nascondersi delle informazioni (tramite public , private , ecc.)
  3. Metodi di membri (originariamente trasformati da macro in codice C al di fuori della struttura con un parametro aggiunto – molte implementazioni sono ancora simili nella pratica).

A questo punto c’erano due problemi. Il primo è che l’accesso predefinito doveva essere pubblico, poiché C non ha informazioni nascoste e quindi da una prospettiva C ++ ha tutto pubblico. Per una buona OO si dovrebbe default al privato. Ciò è stato risolto aggiungendo una class che è praticamente identica a struct tranne per il fatto che l’impostazione predefinita è private piuttosto che public .

L’altro è che questa prospettiva OO dovrebbe avere una class timeval o qualsiasi altra class / struct sullo stesso “footing” di int o char , piuttosto che costantemente annotata nel codice come speciale. Questo è stato risolto rilassando la regola che si deve porre struct (o class ) prima del nome del tipo nel dichiarare una variabile di quel tipo. Quindi struct timeval tv può diventare timeval tv tempo timeval tv .

Questo ha influenzato in seguito i linguaggi OO della syntax C, come Java e C # fino al punto in cui, ad esempio, solo la forma più breve ( timeval tv ) sarebbe una syntax valida in C #.

È semplicemente una differenza nelle lingue. Il C ++ è più permissivo nella sua syntax della struttura.

È proprio come sembra. Pertanto, i seguenti schemi sono piuttosto comuni in C:

 typedef struct YourStructure { int x; // more fields } YourStructure; 

Quindi puoi fare riferimento allo stesso modo come in C ++.

Il modo in cui C viene prima è, ovviamente. Le strutture e le classi in C ++ sono quasi identiche e sarebbe stato molto scomodo richiedere una class con ogni variabile di class, quindi è stata semplificata per entrambi.