Quando usar restringir e não quando
-
08-07-2019 - |
Pergunta
Eu tenho uma compreensão geral de restrict
mas eu estou esperando para esclarecer alguns pontos finos. Eu tenho uma função que lê uma string terminada em null de um buffer e escreve uma versão URL codificado em outro buffer. A função tem esta assinatura (atualmente sem restrict
):
char const *StringUrlEncode(char const *unencoded,
char *encoded,
char *encodedEnd);
unencoded
é a minha seqüência de origem terminada em nulo. O buffer de destino é representada por encoded
e encodedEnd
, onde encoded
aponta para o primeiro char
nos pontos de buffer e encodedEnd
para o primeiro caractere após o tampão, ou seja, a função vai escrever char
s até, mas não incluindo o local apontado por encodedEnd
- este é o seu par begin
/ end
iterador básico Se você estiver familiarizado com as convenções STL C ++
Se eu adicionar restrict
para esta função, deve apenas ser aplicada aos dois primeiros parâmetros:
char const *StringUrlEncode(char const *restrict unencoded,
char *restrict encoded,
char *encodedEnd);
ou se há algum benefício eu não estou entendendo adicionando-à todos os três parâmetros?
Eu posso ver que fazendo a restrict
buffers de entrada e saída ajuda o compilador sabe que eles não se sobreponham. Mas desde o último parâmetro, encodedEnd
, só é usado para marcar o fim do buffer de saída, eu estou pensando que restrict
não seria realmente qualquer ajuda para o compilador aqui (embora eu suponho que não faria mal, que não seja a adição de ruídos desnecessários à declaração de função).
Solução
Tente o artigo de Mike Acton aqui . Restringir é assustador porque de ambos as implicações de desempenho de não usá-lo e as consequências de usá-lo incorretamente.
No seu caso, parece que você poderia aplicar com segurança restringir a todos os três ponteiros como nenhum apelido a mesma área de memória. No entanto, existem vai ser pouco ou nenhum benefício de desempenho de usá-lo no terceiro ponteiro.
Outras dicas
Neste caso em particular não vai fazer a diferença se encodedEnd é restringir ou não; você prometeu o compilador que ninguém aliases unencoded e codificado , e assim que o lê e escreve não irá interferir uns com os outros.
A verdadeira razão que restringem é importante neste caso é que sem ele o compilador não pode saber que escreve através de codificado não afetará lê através unencoded . Por exemplo, se
encoded == unencoded+1
então cada gravação para codificado afetaria cada leitura subseqüente de unencoded , para que o compilador não é possível agendar a carga até que a gravação foi concluída. restringir promessas ao compilador que os dois ponteiros não afetam a mesma memória, para que ele possa agendar cargas com antecedência para barracas de dutos evitar.
Eu acho que você está certo de que não faria mal. O ponteiro loop (chamá-lo p) será igual encodedEnd no final do loop. Mas nada precisa ser acessada após o loop (a partir de qualquer p ou encodedEnd), de modo que não deve ser um problema. Eu não acho que ele vai ajudar, também, porque nada é escrito ou lido a partir encodedEnd então não há nada para otimizar distância.
Mas eu concordo com você ter os dois primeiros restringir deve realmente ajuda.