2010-08-24 18 views
22

Molte delle funzioni della libreria standard C, in particolare quelli per la manipolazione di stringhe, e più in particolare strcpy(), condividere il seguente prototipo:strcpy() valore di ritorno

char *the_function (char *destination, ...) 

Il valore di ritorno di questi le funzioni sono infatti le stesse del destination fornito. Perché dovresti sprecare il valore di ritorno per qualcosa di ridondante? Ha più senso che una tale funzione sia nulla o restituisca qualcosa di utile.

mia unica ipotesi sul motivo per cui questo è è che è più facile e più conveniente per il nido la chiamata di funzione in un'altra espressione, ad esempio:

printf("%s\n", strcpy(dst, src)); 

Ci sono altri motivi ragionevoli per giustificare questo idioma?

+10

La tua ipotesi è corretta, ma ovviamente tutti noi desideriamo queste funzioni restituito un puntatore al byte di terminazione null (che ridurrebbe un sacco di 'O (n)' operazioni a 'O (1)'). –

+0

Un'osservazione molto corretta. Così tante persone non si rendono conto del costo di una strlen(). –

risposta

18

come Evan ha sottolineato, è possibile fare qualcosa di simile

char* s = strcpy(malloc(10), "test"); 

esempio assegnare a malloc()ed un valore, senza utilizzare la variabile di supporto.

(questo esempio non è il migliore, si andrà in crash su di condizioni di memoria, ma l'idea è ovvio)

+3

'char * s = strcpy (xmalloc (10, my_jmpbuf)," test ");' con un 'xmalloc' che esegue' longjmp' in caso di errore renderebbe questo idioma sensato. –

+0

Grazie Yossarian, in questo modo ha molto senso. In generale, se l'argomento di destinazione è un'espressione, il valore restituito potrebbe essere utile in quanto sarebbe il risultato valutato di tale espressione. –

+0

Possibile, sì, molto sciocco, certamente. Il desiderio di evitare una variabile helper è di gran lunga superato dal fatto che il tuo programma bombarderà male. Faresti meglio a usare (o anche scrivere se non ne hai uno) 'strdup': http://stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c/252802 # 252802. – paxdiablo

3

Credo che la tua ipotesi sia corretta, rende più facile nidificare la chiamata.

1

La sua anche estremamente facile da codice.

Il valore di ritorno è in genere lasciato nel registro AX (non è obbligatorio, ma è spesso il caso). E la destinazione viene inserita nel registro AX quando inizia la funzione. Per restituire la destinazione, il programmatore deve fare .... esattamente niente! Basta lasciare il valore dove è.

Il programmatore può dichiarare la funzione come void. Ma quel valore di ritorno è già nel posto giusto, aspetta solo di essere restituito, e non costa nemmeno un'istruzione extra per restituirlo! Non importa quanto piccolo sia il miglioramento, in alcuni casi è utile.

+2

Divertente, non riesco a trovare alcun riferimento a un registro AX nei documenti degli standard ISO C :-) – paxdiablo

+0

Perché quel dettaglio appartiene all'implementazione del compilatore, qualcosa che lo standard ISO non copre. Fa parte della convenzione di chiamata della funzione x86, come indicato [qui] (https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions): "_ I valori interi e gli indirizzi di memoria vengono restituiti nel registro EAX_" – Fernando

0

Non penso che questo sia realmente impostato in questo modo per scopi di nidificazione, ma più per il controllo degli errori. Se la memoria non serve nessuna delle funzioni di libreria standard esegue molto il controllo degli errori da soli e quindi ha più senso che questo sia per determinare se qualcosa è andato storto durante la chiamata strcpy.

if(strcpy(dest, source) == NULL) { 
    // Something went horribly wrong, now we deal with it 
}