2011/2/7 Hung Ruo han <hun...@gmail.com>:
> Boa tarde pessoal,
>
> acidentalmente descobrimos uma dúvida e não conseguimos entender por
> que não dá erro de compilação (acredito que seria erro de sintaxe)...
> espero possam nos ajudar a matar essa curiosidade...
>
O operador virgula e' um operador de sequenciamento, valorando
todos os termos e retornando o ultimo.
--
-alex
http://www.artisancoder.com/
Sinceramente não estou vendo nenhum erro de sintaxe. Pode ser bug
do compilador, qual a mensagem que ele retorna?
O unico problema que eu vejo é que a assinatura do main não é
conforme, mas a maioria dos compiladores aceita. Sem contar que vc não
está retornando nada de uma função que vc diz que retorna inteiro, mas
também a maioria dos compiladores só dá um warning, não um erro.
Att.
Thiago A. Correa
2011/2/7 Hung Ruo han <hun...@gmail.com>:
> --
> Antes de enviar um e-mail para o grupo leia:
> http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
> --~--~---------~--~----~---------------------------------~----------~--~----~
> [&] Colabore com a Pesquisa de Preferência de Conteúdo
> para Eventos do Grupo C & C++ Brasil:
> http://www.surveymonkey.com/s/GBBGTXN
> ------~----~-------~---~---~---~---~----------------~------------~---------~
> [&] C & C++ Brasil - http://www.ccppbrasil.org/
> Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
> Para mais opções, visite http://groups.google.com/group/ccppbrasil
> --~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
> Emprego & carreira: vag...@ccppbrasil.org
> http://groups.google.com/group/dev-guys?hl=en
>
Boa tarde pessoal,
acidentalmente descobrimos uma dúvida e não conseguimos entender por
que não dá erro de compilação (acredito que seria erro de sintaxe)...
espero possam nos ajudar a matar essa curiosidade...
--
Antes de enviar um e-mail para o grupo leia:
http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
--~--~---------~--~----~---------------------------------~----------~--~----~
[&] Colabore com a Pesquisa de Preferência de Conteúdo
para Eventos do Grupo C & C++ Brasil:
http://www.surveymonkey.com/s/GBBGTXN
------~----~-------~---~---~---~---~----------------~------------~---------~
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
Para mais opções, visite http://groups.google.com/group/ccppbrasil
--~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
Emprego & carreira: vag...@ccppbrasil.org
http://groups.google.com/group/dev-guys?hl=en
O código do Pedro contém undefined behvaior, pois modifica a mesma variável
mais de uma vez sem ;. O seu código porém todas as modificações são feitas
apenas uma vez para cada intervalo de sequence point. Então não tem UB.
> On 7 Feb 2011, at 18:13, Murilo Adriano Vasconcelos wrote:
>
> UB?
--
Felipe Magno de Almeida
> 2011/2/7 Gianni <nasus....@gmail.com>:
>> Não.
>> imagine algo mais útil:
>> int x, y;
>> for( x = 1, y = x-1; x != z && y > w; x++, y-- )
>> {
>>
>> Neste código acima há três vírgulas, todas muito úteis e bem definidas.
>
> O código do Pedro contém undefined behvaior, pois modifica a mesma variável
> mais de uma vez sem ;. O seu código porém todas as modificações são feitas
> apenas uma vez para cada intervalo de sequence point. Então não tem UB.
Olha, não sou o maior especialista nisso, mas meu entendimento é que o código do Pedro não tem UB, pois o operador , deve ser resolvido da esquerda p/ direita... logo me parece bem definido e sem ambiguidade.
[snip]
>> O código do Pedro contém undefined behvaior, pois modifica a mesma variável
>> mais de uma vez sem ;. O seu código porém todas as modificações são feitas
>> apenas uma vez para cada intervalo de sequence point. Então não tem UB.
>
> Olha, não sou o maior especialista nisso, mas meu entendimento é que o código do Pedro não tem UB, pois o operador , deve ser resolvido da esquerda p/ direita... logo me parece bem definido e sem ambiguidade.
O problema é a modificação da variável y e x duas vezes no mesmo
intervalo de sequence point.
Independente do operador:
x = ++x;
x = (++x, ++y);
f(++x, ++x);
int& y = x;
x = ++y;
etc
São todos exemplos de undefined behavior.
> --
2011/2/8 Felipe Magno de Almeida <felipe.m...@gmail.com>:
x = (++x, ++y);
f(++x, ++x);
Eu sei.
> Assim sendo, sobre esta sentença:
>
> x = (++x, ++y);
>
> observe que há um "sequence point" após ++x que computa ++y; e este último
> valor será atribuído a x. Como o valor atribuído a x será necessariamente
> computador após ++x então o comportamento parece perfeitamente definido.
Não existe porém um sequence point entre a atribuição e a
sub-expressão (++x, ++y),
apesar de existir um entre ++x e ++y. A implementação pode então
executar a operação
de assignment concorrentemente com ++x e ++y, causando um problema com a
modificação duplicada de x.
> É claro que tais questões são difíceis e demandam consultar um verdadeiro
> especialista.
Se você abrir o link que eu enviei, eles discutem exatamente isto. E
na verdade vários
experts tem opiniões diferentes sobre o caso. Então, well.. vai saber!
Isso se torna
ainda mais complicado com a remoção do sequence point do padrão e a utilização
do conceito de happens-before, que é uma ordem parcial. Sequence points parecem
inseriri uma ordem total, porém não me parece óbvio sobre a relação entre
expressões e sub-expressões.
> --
> P.
|
Veja que a operação de = não requer que a sub-expressão ocorra antes
da avaliação da expressão (++x, ++y), ela pode ocorrer durante. No link
existe uma explicação disso e a resposta abaixo ao Pedro diz o mesmo
com mais detalhes. A resposta de: "comma operator tem um sequence
point entre ++x e a operação conseguinte" já foi dada, não acrescenta
muito bater na mesma tecla.
--
Felipe Magno de Almeida
Não, a ordem de avaliação é unspecified, exceto pelas sub-expressões
do operador comma. A precedência que é da direita para esquerda.
São coisas completamente diferentes.
Você não consegue saber por exemplo qual função é chamada primeiro:
f() + g();
> Cada left-operand do comma operator possui seu
> sequence point exclusivo, e a atribuição pertence à um sequence point
> juntamente com o último (right-most) operando do comma operator.
Não consegui parsear essa frase. A atribuição pertence a um sequence point?
Você quer dizer que a operação de atribuição deve ocorrer somente no final da
avaliação da operação do ultimo operando comma? Onde está escrito isso?
Vou dar um exemplo de mesmo efeito, mas que pode ser mais significativo:
i + (++i, y)
UB ou não?
> Portanto, a
> atribuição só ocorre após a avaliação de todos left-operands.
A única coisa absoluta é que o efeito colateral da atribuição é
percebida no próximo
sequence point após a expressão. Ou seja, o ; no final da linha. Mas quando ela
ocorre não é especificado.
Um exemplo de onde uma atribuição pode ocorrer no meio da expressão:
struct A { A() {} };
int* p = new A;
p pode ser modificado antes da construção de A. Veja que o construtor
de A possui
um sequence point, mesmo assim ele não possui uma relação com a atribuição.
> Se o último operando alterar a mesma variável que está sendo atribuída, é UB.
> Para deixar mais claro o que eu pretendi demonstrar, entre um sequence point
> e outro, um tipo básico só pode ser alterado uma única vez durante e
> avaliação da expressão. Caso contrário, é UB.
Não estou convencido pelos motivos acima e os já expostos.
Interessante porém o seguinte
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637
e http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#222 .
Parece que
i = ++i + i;
Não é UB no draft atual por causa da solução proposta para o 222 que
implica um sequence-point
em (i+=v), sendo que ++i é dado como equilvalente a i+=1 no novo draft.
Porém,
i = i++ + i;
Continua UB pois i++ não implica um sequence-point.
Dei send segundos antes de aparecer seu email :P. Foi mal.
[]'s
2011/2/10 Jardel Weyrich <jwey...@gmail.com>:
> De acordo com meu conhecimento:
> x = (++x, ++y) - OK, pois há um sequence point após a alteração (++x), e
> antes da atribuição.
> x = (++y, ++x) - UB, pois não há sequence point antes da atribuição.
> O resultado de uma expressão com comma operator depende da right-most
> expression (perdoe-me!), então não existe a possibilidade da atribuição
> ocorrer antes do último sequence point.Veja que a operação de = não requer que a sub-expressão ocorra antes
da avaliação da expressão (++x, ++y), ela pode ocorrer durante. No link
existe uma explicação disso e a resposta abaixo ao Pedro diz o mesmo
com mais detalhes. A resposta de: "comma operator tem um sequence
point entre ++x e a operação conseguinte" já foi dada, não acrescenta
muito bater na mesma tecla.
Ela pode ocorrer durante, obviamente ela não pode terminar antes de avaliar a
sub-expressão (++x, ++y), mas ela não precisa começar depois também. Como
a implementação vai fazer é outra história e só cabe ao implementador de um
compilador avaliar a melhor opção. Mas isso não deixa de ser *undefined
behavior*. Se funciona na plataforma X ou Y é irrelevante, pois
undefined behavior
pode também ser o comportamento esperado.
> --
> P.
[]'s
2011/2/11 P. <pedro....@ccppbrasil.org>:
> 1) antes de ++x e antes de ++y
> 2) depois de ++x e antes de ++y
> 3) depois de ++x e depois de ++y
>
> A alternativa (1) é totalmente absurda -- nenhum resultado de subexpressão
> da direita foi computado, não há o que atribuir.
>
> A alternativa (2) é absurda -- o resultado da subexpressão "operador
> vírgula" ainda não foi computado -- sabemos que este resultado é ++y.
>
> A única alternativa dentro das regras é (3).Ela pode ocorrer durante, obviamente ela não pode terminar antes de avaliar a
sub-expressão (++x, ++y), mas ela não precisa começar depois também. Como
a implementação vai fazer é outra história e só cabe ao implementador de um
compilador avaliar a melhor opção. Mas isso não deixa de ser *undefined
behavior*. Se funciona na plataforma X ou Y é irrelevante, pois
undefined behavior
pode também ser o comportamento esperado.
E, como sabemos, a expressão ++y deve necessariamente ser avaliada antes da expressão ++x.
Isso é problema de quem desenvolve o compilador. Se ele quiser
explodir ou lançar
uma bomba atomica por verificar que não existe um happens before ele pode. Além
do que a única coisa importante é o observable behavior, então apesar
de haver uma
ordenação explicita entre ++x e ++y ele pode muito bem executar ++y
antes (inclusive
a CPU pode também reordenar) pois não existe uma ordem entre ++x e x =
(sub-exp).
Então o compilador pode implementar desta forma:
x = ++y,++x;
O observable behavior seria o mesmo se não fosse pelo undefined behavior.
> A máquina concreta pode fazer o que quiser em preparação, desde que o
> resultado da expressão vírgula seja atribuído corretamente no local de
> memória indicado.
>
> E, como sabemos, o resultado da expressão vírgula na sentença acima é o
> resultado da expressão ++y.
>
> E, como sabemos, a expressão ++y deve necessariamente ser avaliada antes da
> expressão ++x.
Não existe porém uma ordenação entre x = () e ++x, portanto esses podem ocorrer
em momentos diferentes. A ordenação de avaliação de ++y e ++x devem ter ordem
somente com relação ao observable behavior. Como não existe nenhum observable
behavior entre esses ele pode reordená-los por exemplo. Taí, dei um
exemplo do que
pode dar errado. Não que fosse necessário.
> Portanto, o significado da sentença é perfeitamente definido.
Não é pois não existe uma ordem entre a atribuição e avaliação do
operador comma.
> Concordo plenamente que o implementador é responsável por se virar para
> realizar esses efeitos na máquina concreta.
> Porém, uma máquina concreta que não produzisse esses efeitos seria
> simplesmente defeituosa.
Não, o programa é defeituoso.
> --
> P.
Typo.
> Acho que tô cansado.
OK.
> --
> p.
S� pra botar pimenta...
char c = 0;
char* x = &c;
*x = (++x, 1);
E a�?
Adriano
Então o compilador pode implementar desta forma:x = ++y,++x;
char c[2] = {0, 0};
char* x = c;
*x = (++x, 1);
Com respeito ao sequence point introduzido no comma está, não existe
diferença de observable behavior entre (++x, ++y) e returnar ++y e
depois ++x. O comportamento só é diferente porque existe um UB por não
haver sequence point relacionando as duas modificações.
++i, i = ++x; é valido porque existe um sequence point entre eles, obrigando
o efeito colateral de ++i ocorrer antes da atribuição.
Em x = (++x, ++y);
não existe uma relação de ordem dos efeitos colaterais entre a atribuição
e ++x. Existe um sequence point da subexpressão (++x, ++y) que obriga
que ++x tenha seu efeito colateral percebido antes ++y, só que ++y não lê
x, portanto é irrelevante a ordem em termos de observable behavior.
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/7237511481a9816e?hl=en