Domanda

Supponiamo che io abbia una funzione

void foo(char *)

che, internamente, deve trattare suo ingresso come un blocco di byte NUL-terminati (per esempio, è una funzione hash sulle stringhe). Potrei lanciare l'argomento per unsigned char* nella funzione. Potrei anche cambiare la dichiarazione di

void foo(unsigned char *)

Ora, dato che char, signed char e unsigned char sono tre tipi diversi , sarebbe questo costituirebbe un cambiamento di interfaccia, sotto qualsiasi ragionevole definizione del termine "interfaccia" in C?

(Questa domanda ha lo scopo di risolvere una sollevata dal un'altra domanda. ho le mie opinioni, ma non accetterà una risposta fino a quando si arriva come un "vincitore" dai voti degli altri.)

È stato utile?

Soluzione

Secondo la norma ISO / IEC 9899: TC3,

  • chiamare una funzione tramite un'espressione di tipo incompatibile è un comportamento indefinito (6.5.2.2 § 9)
  • tipi di funzione compatibile deve avere tipi di parametri compatibili (6.7.5.3 §15)
  • tipi di puntatore compatibili deve puntare a tipi compatibili (6.7.5.1 §2)
  • char, signed char e unsigned char sono diversi tipi di base (6.2.5 § 14) e quindi incompatibile (6.2.7 §1), che è anche esplicitamente menzionato nella nota 35 a pagina 35

Quindi sì, questo è chiaramente un cambiamento per l'interfaccia di programmazione.

Tuttavia, come char *, signed char * e unsigned char * avranno rappresentazioni identici e requisiti di allineamento in qualsiasi implementazione sano del linguaggio C, l'interfaccia binaria rimarrà invariata.

Altri suggerimenti

Sì, lo è. Il codice client che in precedenza compilato non sarà più di compilazione (o comunque è in grado di generare nuove avvertenze), quindi questo è un cambiamento di rottura.

I scegliere "C - nessuno dei precedenti."

Anche se non è una risposta diretta alla domanda che in realtà ha chiesto, la soluzione giusta per la situazione sembra abbastanza semplice e ovvio per me:. Non si dovrebbe davvero utilizzare una di queste

Almeno IMO, si dispone di una buona ragione per fare altrimenti, la funzione dovrebbe accettare un void * o (preferibilmente) void const *. Quello che stai cercando è fondamentalmente un puntatore opaco, e questo è esattamente ciò che void * fornisce. L'utente non ha bisogno di sapere nulla riguardo la struttura interna della vostra implementazione, e dal momento che qualsiasi altro tipo di puntatore convertirà al void * implicitamente, è una delle poche possibilità che non si rompe qualsiasi codice esistente sia.

Esiste un char * implicitamente convertire in un unsigned char *?

  • Sì - non si è rotto l'interfaccia
  • No - hai trapelare implementazione
    i dettagli.

No, non è. Qualsiasi modifica al codice del client è banale (soprattutto se è solo per evitare un avvertimento), e, in pratica, in praticamente qualsiasi applicazione C vi accorgerete che non hanno nemmeno bisogno di una ri-compilazione perché puntatori a char* e unsigned char* saranno passati esattamente allo stesso modo nella convenzione di chiamata.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top