Molti degli argomenti di questo argomento sono semplicemente soggettivi e l'argomento su "la stella si lega al nome della variabile" è ingenuo. Ecco alcuni argomenti che non sono solo opinioni:
Qualificatori del tipo di puntatore dimenticati
Formalmente, la "stella" non appartiene né al tipo né al nome della variabile, fa parte del suo elemento grammaticale chiamato puntatore . La sintassi C formale (ISO 9899: 2018) è:
(6.7) dichiarazione:
specificatori di dichiarazione init-dichiarator-list opt ;
Dove specificatori di dichiarazione contiene il tipo (e l'archiviazione) e l' elenco init-dichiarator contiene il puntatore e il nome della variabile. Che vediamo se analizziamo ulteriormente questa sintassi dell'elenco dei dichiaratori:
(6.7.6) dichiaratore:
puntatore opt -dichiaratore diretto
...
(6.7.6) puntatore:
* tipo-qualificatore-lista opt
* tipo-qualificatore-lista puntatore opt
Laddove un dichiarante è l'intera dichiarazione, un dichiaratore diretto è l'identificatore (nome della variabile) e un puntatore è la stella seguita da un elenco di qualificatori di tipo facoltativo che appartiene al puntatore stesso.
Ciò che rende incoerenti i vari argomenti di stile su "la stella appartiene alla variabile" è che si sono dimenticati di questi qualificatori di tipo puntatore. int* const x, int *const xO int*const x?
Considera int *const a, b;, quali sono i tipi di ae b? Non è così ovvio che "la stella appartiene alla variabile". Piuttosto, si inizierebbe a riflettere su doveconst appartiene.
Puoi sicuramente sostenere che la stella appartiene al qualificatore del tipo di puntatore, ma non molto oltre.
L'elenco dei qualificatori di tipo per il puntatore può causare problemi a chi utilizza lo int *astile. Coloro che usano i puntatori all'interno di un typedef(cosa che non dovremmo, pessima pratica!) E pensano che "la stella appartiene al nome della variabile" tendono a scrivere questo bug molto sottile:
/*** bad code, don't do this ***/
typedef int *bad_idea_t;
...
void func (const bad_idea_t *foo);
Questo si compila in modo pulito. Ora potresti pensare che il codice sia stato reso corretto. Non così! Questo codice è accidentalmente una correttezza const falsa.
Il tipo di fooè in realtà int*const*- il puntatore più esterno è stato reso di sola lettura, non i dati puntati. Quindi all'interno di questa funzione possiamo fare**foo = n; e cambierà il valore della variabile nel chiamante.
Questo perché nell'espressione const bad_idea_t *foo, qui *non appartiene al nome della variabile! Nello pseudo codice, questa dichiarazione di parametro deve essere letta come const (bad_idea_t *) fooe non come (const bad_idea_t) *foo. La stella appartiene al tipo di puntatore nascosto in questo caso: il tipo è un puntatore e un puntatore qualificato const è scritto come *const.
Ma poi la radice del problema nell'esempio sopra è la pratica di nascondere i puntatori dietro a typedefe non lo *stile.
Per quanto riguarda la dichiarazione di più variabili su una sola riga
La dichiarazione di più variabili su una sola riga è ampiamente riconosciuta come cattiva pratica 1) . CERT-C lo riassume bene come:
DCL04-C. Non dichiarare più di una variabile per dichiarazione
Basta leggere l'inglese, quindi il buon senso concorda sul fatto che una dichiarazione dovrebbe essere una dichiarazione.
E non importa se le variabili sono puntatori o meno. Dichiarare ogni variabile su una sola riga rende il codice più chiaro in quasi tutti i casi.
Quindi l'argomento sul confondersi del programmatore int* a, bè negativo. La radice del problema è l'uso di più dichiaratori, non il posizionamento di *. Indipendentemente dallo stile, dovresti invece scrivere questo:
int* a; // or int *a
int b;
Un altro argomento valido ma soggettivo sarebbe quello dato int* ail tipo di aè senza dubbioint* e quindi la stella appartiene al qualificatore di tipo.
Ma sostanzialmente la mia conclusione è che molti degli argomenti pubblicati qui sono solo soggettivi e ingenui. Non puoi davvero fare un valido argomento per entrambi gli stili - è davvero una questione di preferenze personali soggettive.
1) CERT-C DCL04-C .
typedefs, ma ciò aggiungerà complessità non necessaria, IMHO.