Domanda

Ho una comprensione generale di restring ma spero di chiarire alcuni punti. Ho una funzione che legge una stringa con terminazione null da un buffer e scrive una versione codificata URL in un altro buffer. La funzione ha questa firma (attualmente senza restring ):

char const *StringUrlEncode(char const *unencoded, 
                            char *encoded,
                            char *encodedEnd);

non codificato è la mia stringa di origine con terminazione null. Il buffer di destinazione è rappresentato da codificato e encodedEnd , dove codificato punta al primo carattere nel buffer e < code> encodedEnd punta al primo carattere dopo il buffer, ovvero la funzione scriverà char fino a non includendo il posizione indicata da encodedEnd - questa è la tua coppia di iteratori inizio / fine di base se hai familiarità con le convenzioni C ++ STL.

Se aggiungo restring a questa funzione, dovrebbe essere applicato solo ai primi due parametri:

char const *StringUrlEncode(char const *restrict unencoded, 
                            char *restrict encoded,
                            char *encodedEnd);

o c'è qualche vantaggio che non capisco aggiungendolo a tutti e tre i parametri?

Vedo che rendere i buffer di input e output restring aiuta il compilatore a sapere che non si sovrappongono. Ma poiché l'ultimo parametro, encodedEnd , viene utilizzato solo per contrassegnare la fine del buffer di output, sto pensando che restring non sarebbe davvero di alcun aiuto per il compilatore qui (anche se suppongo che non farebbe male, a parte l'aggiunta di rumore non necessario alla dichiarazione di funzione).

È stato utile?

Soluzione

Prova l'articolo di Mike Acton qui . La restrizione è spaventosa a causa sia delle implicazioni in termini di prestazioni del non utilizzo che delle conseguenze dell'uso errato.

Nel tuo caso, sembra che potresti tranquillamente applicare la limitazione a tutti e tre i puntatori poiché nessuno alias è la stessa area di memoria. Tuttavia, ci sarà poco o nessun vantaggio in termini di prestazioni dall'usarlo sul terzo puntatore.

Altri suggerimenti

In questo caso particolare non farà alcuna differenza se encodedEnd è limitato o meno; hai promesso al compilatore che nessuno alias non codificato e codificato , e quindi le letture e le scritture non interferiranno l'una con l'altra.

La vera ragione per cui la limitazione è importante in questo caso è che senza di essa il compilatore non può sapere che le scritture tramite codificate non influenzeranno le letture attraverso non codificate . Ad esempio, se

encoded == unencoded+1

quindi ogni scrittura su codificata influirebbe su ogni lettura successiva da non codificata , quindi il compilatore non può pianificare il caricamento fino al completamento della scrittura. Limit promette al compilatore che i due puntatori non influiscono sulla stessa memoria, quindi può pianificare i carichi abbastanza in anticipo per evitare blocchi della pipeline.

Penso che tu abbia ragione che non farebbe male. Il puntatore del loop (chiamalo p) sarà uguale codificatoEnd alla fine del loop. Ma non è necessario accedere a nulla dopo il ciclo (da p o encodedEnd), quindi non dovrebbe essere un problema. Non penso che possa essere d'aiuto, perché nulla è mai stato scritto o letto da encodedEnd, quindi non c'è nulla da ottimizzare.

Ma sono d'accordo con te che i primi due limiti dovrebbero davvero aiutare.

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