I puntatori opachi dovrebbero essere puntatori o tipi?

2

Un modo comune per implementare "PIMPL" in C è quello di fare questo:

typedef struct _Opaque Opaque;

Opaque* createOpaque();
void doSomething(Opaque *opaque);

o

typedef struct _Opaque* Opaque;

Opaque createOpaque();
void doSomething(Opaque opaque);

Il primo richiede che il chiamante tratti Opaque come puntatore, il secondo richiede che il chiamante tratti Opaque come valore.

Gli asterischi non rendono il codice più leggibile, ma ci sono pericoli nascosti di typedef ingerirlo? Data la scelta tra i due stili, che dovrebbe essere preferito?

    
posta user112513312 01.04.2017 - 08:01
fonte

1 risposta

5

È una questione di gusti, ma preferisco molto il primo stile in C: avere opaco struct con puntatore esplicito e sistematico a loro. BTW, GTK sta seguendo sistematicamente questo stile. E lo standard <stdio.h> con FILE .

C è un linguaggio di basso livello e il programmatore si aspetta di comprendere i dettagli di basso livello. Di solito si aspetta di sapere (o intuire) le dimensioni di un determinato tipo. Sa che passare un puntatore è molto veloce. E il programmatore dovrebbe sapere che è un puntatore. Altrimenti, potrebbe essere tentato (dopo diversi livelli di software) di "passare per riferimento", di passare un puntatore a quella cosa opaca.

In C a volte puoi passare un struct in base al valore, e in effetti tutti i dati sono copiati quando lo fai. A volte questo è buono, quando struct è piccolo (ad esempio struct Point_st { int x, y;} per le coordinate cartesiane ...). Ma in altri casi, è inefficiente (ad esempio, probabilmente non si vuole passare un intero struct stat da stat (2) in base al valore).

Finalmente, su alcuni ABI (in particolare x86-64 per Linux) potrebbe esserci una convenzione di chiamata speciale per small struct . Su x86-64 un struct con due campi del puntatore viene restituito attraverso i registri (non usando alcuna zona di memoria per quello).

In altre lingue (Go in particolare, e probabilmente C ++) la situazione è diversa, e il secondo stile è preferibile (ma C ++ ha const Opaque& per passare da "riferimento costante", in effetti "nascondendo" un puntatore).

The asterisks don't make the code any more readable,

Questa è la tua opinione e non sono d'accordo. Rendono il codice IMHO molto più leggibile.

    
risposta data 01.04.2017 - 08:20
fonte

Leggi altre domande sui tag