O acesso a um objeto não volátil declarado através de uma referência / ponteiro volátil confere regras voláteis aos referidos acessos?
Será longo, para contextualizá-lo e fornecer o máximo de informações possível, preciso percorrer vários links e citações - como costuma ser a única maneira de entrar no C / C ++ Standard Rabbit Hole. Se você tiver melhores citações ou outras melhorias para este post, entre em contato. Mas, para resumir de antemão,você pode culpar @zwol para mim postar isso ;-) e o objetivo é encontrar a verdade dentre duas proposições:
Os padrões C e (por importação; ver comentários) C ++ exigem que os acessos viavolatile *
ouvolatile &
deve se referir a um objeto originalmente declaradovolatile
para tervolatile
semântica?Ouestá acessando umvolatile
objeto qualificado por meio de umvolatile
ponteiro / referência suficiente / suposto para fazer com que os referidos acessos se comportem como se o objeto fosse declaradovolatile
?De qualquer forma, se (como parece) a redação for um tanto ambígua em comparação com a intenção -podemos deixar isso claro nas próprias normas?
A primeira dessas interpretações mutuamente exclusivas é mais comumente realizada, e isso não é totalmente sem base. No entanto, espero mostrar que há uma quantidade significativa de "dúvida razoável" a favor do 2º - especialmente quando voltamos a algumas passagens anteriores nos documentos do Rationale and WG Papers.
volatile
Pergunta popular de ontemA definição de "volátil" é volátil ou o GCC está tendo alguns problemas de conformidade padrão? surgiu assumindo umavolatile
referência confeririavolatile
comportamento nãovolatile
referente - mas descobrindo que isso não aconteceu ou ocorreu em graus variados e de maneira imprevisível.
A resposta aceita inicialmente concluiu que apenas o tipo declarado de referente era importante. Este e muitos comentários pareciam concordar que princípios equivalentes estão em jogo, como sabemos bem porconst
: o comportamento seria apenasvolatile
(ou definido) se a referência tiver o mesmocv-qualificação como o objeto referido:
A palavra-chave nessa passagem é objeto.volatile sig_atomic_t flag;
é um objeto volátil.*(volatile char *)foo
é meramenteum acesso através de um valor qualificado de volátil e a norma não exige que isso tenha efeitos especiais. -zwol
Essa interpretação parece ser amplamente aceita, como visto nas respostas a essa pergunta semelhante, mas espero que não seja duplicada:Requisitos para o comportamento de apontar ponteiro para volátil para objeto não volátil Mas ainda há incerteza: logo após a resposta dizer 'não', então diz 'talvez'! Enfim ... vamos verificar o padrão para ver em que os 'não' se baseiam.
C11,N1548, §6.7.3: Considerando que é claro que é UB acessar um objetodefinido com volatile
ouconst
digite através de um ponteiro que não compartilhe o qualificador ...
6 Se for feita uma tentativa de modificar um objeto definido com umconst
qualificado pelo uso de um valor l com valores nãoconst
-qualificado, o comportamento é indefinido. Se for feita uma tentativa de se referir aum objeto definido com umvolatile
tipo qualificado através do uso de um valor l comvolatile-
tipo qualificado, o comportamento é indefinido. (133)
... a Norma não parece mencionar explicitamente o cenário oposto, nomeadamente paravolatile
. Além disso, ao resumirvolatile
e operações sobre ele, agora fala sobre um objeto quetem volatile
tipo qualificado:
7 Aobjeto que possuivolatile
tipo qualificado pode ser modificado de maneiras desconhecidas para a implementação ou ter outros efeitos colaterais desconhecidos. Portanto, qualquer expressão referente a esse objeto deve ser avaliada estritamente de acordo com as regras da máquina abstrata, conforme descrito em 5.1.2.3. Além disso, em cada ponto da sequência, o valor armazenado pela última vez no objeto deve concordar com o prescrito pela máquina abstrata, exceto conforme modificado pelos fatores desconhecidos mencionados anteriormente. (134) O que constitui um acesso a um objeto que possuivolatile
tipo qualificado é definido pela implementação.
Devemos assumir que "has" é equivalente a "foi definido com"? oupode "tem" refere-se a uma combinação de objeto e qualificadores de referência?
Um comentarista resumiu bem a questão com este tipo de redação:
Den1548 §6.7.3 ¶6 a norma usa a frase "objeto definido com um tipo qualificado para uso volátil" para distingui-lo de "lvalue com tipo qualificado para uso volátil". É lamentável que esse "objeto definido com a distinção" versus "lvalue" não continue, e o padrão use "objeto que possui um tipo qualificado de volátil" e diz que "o que constitui acesso a um objeto que tem um tipo qualificado de volátil é definido pela implementação "(que poderia ter dito" lvalue "ou" objeto definido com "para maior clareza). Ah bem. -Dietrich Epp
O parágrafo 4 da mesma seção parece ser menos frequentemente citado, mas pode ser relevante, como veremos na próxima seção.
volatile
ponteiro / referência destinado a conferirvolatile
semântica em sua desreferência?A resposta acima mencionada tem um comentário em que o autor cita uma declaração anterior do Comitê que põe em dúvida a idéia 'a referência deve corresponder ao referente':
Curiosamente, há uma frase lá [C99 Justificativa paravolatile
] implica que o comitêsignificava para*(volatile T*)x
para forçar esse acesso ax
ser tratado como volátil; mas a redação real do padrão não alcança isso. - zwol
Podemos encontrar um pouco mais de informações sobre esse trecho da justificativa, a partir do segundo tópico mencionado acima:Requisitos para o comportamento de apontar ponteiro para volátil para objeto não volátil
Por outro lado,esta postagem citações do 6.7.3 do Rationale for International Standard - Linguagens de programação - C:
Uma conversão de um valor para um tipo qualificado não tem efeito; a qualificação (volátil, digamos) não pode afetar o acesso, uma vez que ocorreu antes do caso.Se for necessário acessar um objeto não volátil usando semântica volátil, a técnica é converter o endereço do objeto no tipo apropriado de ponteiro para qualificado e desreferenciar esse ponteiro.
—philipxy
E deesse segmento de bytes, nos referimos a C99 s6.7.3 p3 - também conhecido como p11 de C11 - e a esta análise:
O parágrafo em questão é um pouco antes da seção 6.7.3.1 no documento de justificativa. Se você também precisar citar o próprio documento padrão, cite6.7.3 p3:
As propriedades associadas aos tipos qualificados são significativas apenas para expressões que são lvalues.
A expressão(volatile WHATEVER) non_volatile_object_identifier
énão um valor l, portanto o qualificador 'volátil' não tem sentido.
Por outro lado, a expressão* (volatile WHATEVER *) & non_volatile_object_identifier
é um valor (pode ser colocado no lado esquerdo de uma declaração de atribuição), portanto, a propriedade do qualificador 'volátil' tem o significado pretendido neste caso.
—Tim Rentsch
Existe ummuito demonstração específica de apoio a esta ideia, com especial atenção à 1ª questão ligada, emWG PaperN1381. Isto introduziu o anexomemset_s()
para fazer o que o OP queria - garantir um preenchimento não-exagerado da memória. Ao discutir possíveis implementações, parece apoiar a idéia - omitindo declarar qualquer requisito - de que usar umvolatile
apontador para alterar umvolatile
objetodevemos gerar código com base noqualificador do ponteiro, independentemente do objeto referido ...
void *secure_memset(void *v, int c , size_t n) {
volatile unsigned char *p = v;
while (n--) *p++ = c;
return v;
}
Essa abordagem impedirá que a limpeza da memória seja otimizada edeve funcionar em qualquer plataforma compatível com os padrões.
... e que os compiladores que não estão fazendo isso estão informados ...
Houve um aviso recente de quealguns compiladores violam o padrão nem sempre respeitando ovolatile
qualificador.
Isso foi cansativo. Certamente há muito espaço para interpretação aqui, dependendo de quais documentos você leu versus quais não, e como você escolhe interpretar muitas palavras que não são específicas o suficiente. Parece claro que algo está errado:
a justificativa e N1381 têm palavras erradas ou aleatoriamente, oueles foram especificamente invalidados retroativamente ... ouo Padrão é redigido de maneira errada ou aleatória.Espero que possamos fazer melhor do que toda a ambiguidade e especulação que parece ter cercado isso no passado - e obter uma declaração mais conclusiva registrada. Para esse fim, quaisquer outras fontes e pensamentos de especialistas serão muito bem-vindos.