Um ponto de seqüência em uma linguagem imperativa define um
ponto na execução de um programa em que é
garantido que todos os efeitos colaterais das avaliações anteriores
terão sidos realizados, e nenhum efeitos colaterais das avaliações subseqüente
foram realizados ainda.
A adição de um ou mais ponto de seqüência é um método de
garantir um resultado consistente, porque restringe algumas possíveis ordens de
avaliação. Como conseqüência pode reduzir o paralelismo entre as instruções.
Considere a funções f() e g(). Na linguagem C e C++, o
operador + não está associado com um ponto de seqüência e, portanto a expressão
f() + g() pode ter as seguintes ordens de avaliação:
Ordem 1
|
Ordem 2
|
f()
|
g()
|
g()
|
f()
|
f() + g()
|
f() + g()
|
O resultado dessa expressão pode ser indefinido dependendo
dos efeitos colaterais das funções f() e g().
Os pontos de seqüências também aparecem quando uma variável
é modificada mais de uma vez em uma mesma expressão. Um exemplo de uma expressão
em C é i=i++, que aparentemente temos
uma atribuição do valor de i para a variável i e depois o valor de i é
incrementado. O valor final de i é ambíguo porque dependendo da ordem de
avaliação de expressão, o incremento pode acontecer antes, depois ou intercalada
com a atribuição. No caso, essa avaliação gera um comportamento indefinido.
Claúsula 6.5.2 Between the previous and next sequence
point an object shall have its stored value modified at most once by the
evaluation of an expression. Furthermore, the prior value shall be read only to
determine the value to be stored.
A avaliação de
uma expressão não pode ter o seu valor alterado no máximo uma vez.
Considere o seguinte exemplo de avaliação da expressão
i=i++. Vamos supor que o valor i é 5.
Ordem 1
|
Ordem 2
|
Ordem 3
|
i++
|
i=i
|
Pegar o valor de i
|
i = i
|
i++
|
i++
|
i = 6
|
i=6
|
Atribui o valor de i
|
i=5
|
Note que em uma das avaliações, o valor de i não é
modificado.
Um ponto de seqüência
acontece antes da chamada da função. A ordem em que os argumentos da função são
avaliados não é especificada, mas o ponto de seqüência significa que todos os
efeitos colaterais são completados antes da entrada da função. Na expressão
f(i++)+g(j++)+h(k++), a função f é chamada com o valor original do parâmetro i,
mas o valor é incrementado antes da entrada da função.
int i=5;
int f(int j){
printf("%d %d\n",j,i);
}
int main(){
f(i++);
return 0;
}
Saída
5 6
Por outro
lado, não é especificado a ordem que as funções f(),g() e h() são executados, nem a ordem que são
incrementados os valores de i,j,k. As variáveis j e k no corpo de f pode ou não já terem sido incrementados.
Considere
o seguinte programa:
int i=5;
int j=5;
int k=5;
int f(int x){
printf("f
%d %d %d\n",i,j,k);
return x;
}
int g(int x){
printf("g %d %d %d\n",i,j,k);
return x;
}
int h(int x){
printf("h %d %d %d\n",i,j,k);
return x;
}
int main(){
int l;
f(i++) + g(j++) + h(k++);
return 0;
}
O resultado no meu
compilador foi:
f 6 5 5
g 6 6 5
h 6 6 6
Alguns pontos de seqüência estabelecidas na especificação
do C:
·
O ponto de chamada uma função,
depois de avaliar os seus argumentos
·
O final do primeiro operando do operador &
&
·
O final do primeiro operando do operador | |
·
O final do primeiro operando do: operador
condicional.
·
O fim do operando cada um o operador vírgula. i=i,i++
·
As expressões o controle em do,
while, if, switch ou for
·
As outras duas expressões em
uma instrução for
·
A expressão em uma instrução de retorno.
ACSL: ANSI/ISO C Specification Language
Version 1.4
ISO/IEC 9899:TC2
Nenhum comentário:
Postar um comentário