sintaxe c++

23 views
Skip to first unread message

Hung Ruo han

unread,
Feb 7, 2011, 12:57:40 PM2/7/11
to ccppbrasil
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...

<code>
#include <iostream>

int main ()
{
int x = (1, 2, 3, 4);

std::cout << "x = " << x << std::endl;
}
</code>

Att
Hung

Alex Queiroz

unread,
Feb 7, 2011, 1:01:45 PM2/7/11
to ccppb...@googlegroups.com
Hallo,

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/

Thiago A. Corrêa

unread,
Feb 7, 2011, 1:09:52 PM2/7/11
to ccppb...@googlegroups.com
Olá,

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
>

P.

unread,
Feb 7, 2011, 2:54:43 PM2/7/11
to ccppb...@googlegroups.com
On Monday, February 7, 2011 3:57:40 PM UTC-2, Hung Ruo han wrote:
 
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...

Você descobriu o intrigante operador vírgula.

Experimenta esse:

#include <iostream>
int main (int argc, char * argv [])
{
    int x = 0;
    int y = 1;
    int y = (++x, ++y);
    int x = (++y, ++x);
    std::cout << "{ " << x << ", " << y << " }" << std::endl;
    return 0;
}

--
 P.

Murilo Adriano Vasconcelos

unread,
Feb 7, 2011, 3:13:50 PM2/7/11
to ccppb...@googlegroups.com
UB?

--
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



--
Murilo Adriano Vasconcelos
http://murilo.wordpress.com

Gianni

unread,
Feb 7, 2011, 3:26:48 PM2/7/11
to ccppb...@googlegroups.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.

Felipe Magno de Almeida

unread,
Feb 7, 2011, 3:41:39 PM2/7/11
to ccppb...@googlegroups.com
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.

> On 7 Feb 2011, at 18:13, Murilo Adriano Vasconcelos wrote:
>
> UB?


--
Felipe Magno de Almeida

Gianni

unread,
Feb 8, 2011, 7:27:11 AM2/8/11
to ccppb...@googlegroups.com

On 7 Feb 2011, at 18:41, Felipe Magno de Almeida wrote:

> 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.

Felipe Magno de Almeida

unread,
Feb 8, 2011, 7:33:20 AM2/8/11
to ccppb...@googlegroups.com
2011/2/8 Gianni <nasus....@gmail.com>:

>
> On 7 Feb 2011, at 18:41, Felipe Magno de Almeida wrote:

[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.

> --

Felipe Magno de Almeida

unread,
Feb 8, 2011, 7:41:35 AM2/8/11
to ccppb...@googlegroups.com

P.

unread,
Feb 10, 2011, 1:57:15 PM2/10/11
to ccppb...@googlegroups.com
On Tuesday, February 8, 2011 10:33:20 AM UTC-2, Felipe Magno de Almeida wrote:

x = (++x, ++y);
f(++x, ++x);

 
Essas duas linhas não são parecidas.

Apesar da sequência de tokens, f(++x, ++x) não é um caso do operador vírgula.

Em uma expressão com o operador vírgula, cada vírgula indica um "sequence point".

Porém, em uma expressão de chamada de função, cada vírgula NÃO indica um "sequence point".

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.

É claro que tais questões são difíceis e demandam consultar um verdadeiro especialista.

--
 P.

Felipe Magno de Almeida

unread,
Feb 10, 2011, 2:34:41 PM2/10/11
to ccppb...@googlegroups.com
2011/2/10 P. <pedro....@ccppbrasil.org>:

> On Tuesday, February 8, 2011 10:33:20 AM UTC-2, Felipe Magno de Almeida
> wrote:
>>
>> x = (++x, ++y);
>> f(++x, ++x);
>
>
> Essas duas linhas não são parecidas.
>
> Apesar da sequência de tokens, f(++x, ++x) não é um caso do operador
> vírgula.
>
> Em uma expressão com o operador vírgula, cada vírgula indica um "sequence
> point".
>
> Porém, em uma expressão de chamada de função, cada vírgula NÃO indica um
> "sequence point".

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.

Jardel Weyrich

unread,
Feb 10, 2011, 2:59:27 PM2/10/11
to ccppb...@googlegroups.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.

2011/2/10 Felipe Magno de Almeida <felipe.m...@gmail.com>

Gianni

unread,
Feb 10, 2011, 3:06:51 PM2/10/11
to ccppb...@googlegroups.com
De acordo com o site cplusplus.com, não é UB, eles até tem isso como um exemplo aqui: http://www.cplusplus.com/doc/tutorial/operators/

Comma operator ( , )

The comma operator (,) is used to separate two or more expressions that are included where only one expression is expected. When the set of expressions has to be evaluated for a value, only the rightmost expression is considered.

For example, the following code:

 
a = (b=3, b+2);


Would first assign the value 3 to b, and then assign b+2 to variable a. So, at the end, variable a would contain the value 5 while variable b would contain value 3.

Jardel Weyrich

unread,
Feb 10, 2011, 3:20:54 PM2/10/11
to ccppb...@googlegroups.com
x = (0, ++x); equivale à x = ++x;.

E este é um caso de UB, pois você não pode alterar e atribuir a mesma variável sem um sequence point entre estas operações. Por isto citei os 2 exemplos no email anterior. O comma operator introduz um sequence point após computar cada left-expression, mas não após a right-most expression.

2011/2/10 Gianni <nasus....@gmail.com>

Felipe Magno de Almeida

unread,
Feb 10, 2011, 4:52:19 PM2/10/11
to ccppb...@googlegroups.com
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.

--
Felipe Magno de Almeida

Jardel Weyrich

unread,
Feb 10, 2011, 6:14:00 PM2/10/11
to ccppb...@googlegroups.com
Errado.

A expressão é avaliada da esquerda para a direita, e o operador coma introduz N sequence points. 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. Portanto, a atribuição só ocorre após a avaliação de todos left-operands. 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.

Jardel Weyrich

unread,
Feb 10, 2011, 6:14:33 PM2/10/11
to ccppb...@googlegroups.com
Perdão, da direita para a esquerda.

2011/2/10 Jardel Weyrich <jwey...@gmail.com>

Jardel Weyrich

unread,
Feb 10, 2011, 7:11:06 PM2/10/11
to ccppb...@googlegroups.com
Oh, aparentemente sou eu quem está errado sobre a questão da atribuição.

Iniciei um debate sobre isto, e mencionaram que a ordem de avaliação dos operadores da atribuição não é especificada, e deve ser vista como um operator=(lhs, rhs). Sendo assim, o exemplo que eu citei como OK também pode ser UB.
Outro exemplo que surgiu: (++y, ++x) = (++x, ++y) // Boa sorte!

Concluindo, vou me calar antes que o Felipe me critique por ter dito erroneamente que ele estava errado. Perdão :)

2011/2/10 Jardel Weyrich <jwey...@gmail.com>

Felipe Magno de Almeida

unread,
Feb 10, 2011, 7:32:59 PM2/10/11
to ccppb...@googlegroups.com
2011/2/10 Jardel Weyrich <jwey...@gmail.com>:

> Errado.
> A expressão é avaliada da esquerda para a direita, e o operador coma
> introduz N sequence points.

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.

Felipe Magno de Almeida

unread,
Feb 10, 2011, 7:33:43 PM2/10/11
to ccppb...@googlegroups.com
2011/2/10 Jardel Weyrich <jwey...@gmail.com>:

> Oh, aparentemente sou eu quem está errado sobre a questão da atribuição.
> Iniciei um debate sobre isto, e mencionaram que a ordem de avaliação dos
> operadores da atribuição não é especificada, e deve ser vista como um
> operator=(lhs, rhs). Sendo assim, o exemplo que eu citei como OK também pode
> ser UB.
> Outro exemplo que surgiu: (++y, ++x) = (++x, ++y) // Boa sorte!
> Concluindo, vou me calar antes que o Felipe me critique por ter dito
> erroneamente que ele estava errado. Perdão :)

Dei send segundos antes de aparecer seu email :P. Foi mal.

[]'s

P.

unread,
Feb 11, 2011, 7:39:12 AM2/11/11
to ccppb...@googlegroups.com
On Thursday, February 10, 2011 7:52:19 PM UTC-2, Felipe Magno de Almeida wrote:
 
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.


Não, mas esclarece bastante.

Repetindo a sentença em questão:

x = (++x, ++y);

Em que ordem as sub expressões podem ser avaliadas?

Certamente a sub expressão de atribução não pode ser avaliada "concorrentemente" com ++x e ++y -- ela pode ser, apenas, ordenada ou reordenada de várias maneiras.

Antes de mais nada, nós sabemos que, qualquer que seja a reordenação, ++x deve necessariamente completar antes de ++y -- a tecla que já foi batida várias vezes.

Assim, a atribuição pode ocorrer:

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).

--
 P.


Felipe Magno de Almeida

unread,
Feb 11, 2011, 7:52:51 AM2/11/11
to ccppb...@googlegroups.com
2011/2/11 P. <pedro....@ccppbrasil.org>:

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

P.

unread,
Feb 11, 2011, 8:06:57 AM2/11/11
to ccppb...@googlegroups.com
On Friday, February 11, 2011 10:52:51 AM UTC-2, Felipe Magno de Almeida wrote:
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.


Qual é o sentido de "começar antes"?
Como um operador de atribuição pode "começar antes" da existência do valor a ser atribuído?

O que a avaliação de uma atribuição pode fazer antes da existência do valor a ser atribuído?
Fazer alongamento?
Esquentar o motor?
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.

Portanto, o significado da sentença é perfeitamente definido.

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.

--
 P.

P.

unread,
Feb 11, 2011, 8:08:29 AM2/11/11
to ccppb...@googlegroups.com
On Friday, February 11, 2011 11:06:57 AM UTC-2, P. wrote:


E, como sabemos, a expressão ++y deve necessariamente ser avaliada antes da expressão ++x.

__depois__, avaliada __depois__...

Acho que tô cansado.

--
p.

Felipe Magno de Almeida

unread,
Feb 11, 2011, 8:29:13 AM2/11/11
to ccppb...@googlegroups.com
2011/2/11 P. <pedro....@ccppbrasil.org>:

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.

Felipe Magno de Almeida

unread,
Feb 11, 2011, 8:29:29 AM2/11/11
to ccppb...@googlegroups.com
2011/2/11 P. <pedro....@ccppbrasil.org>:

> On Friday, February 11, 2011 11:06:57 AM UTC-2, P. wrote:
>>
>> E, como sabemos, a expressão ++y deve necessariamente ser avaliada antes
>> da expressão ++x.
>
> __depois__, avaliada __depois__...

Typo.

> Acho que tô cansado.

OK.

> --
> p.

Adriano dos Santos Fernandes

unread,
Feb 11, 2011, 8:36:01 AM2/11/11
to ccppb...@googlegroups.com
Pessoal,

S� pra botar pimenta...

char c = 0;
char* x = &c;

*x = (++x, 1);

E a�?


Adriano

P.

unread,
Feb 11, 2011, 8:38:12 AM2/11/11
to ccppb...@googlegroups.com
On Friday, February 11, 2011 11:29:13 AM UTC-2, Felipe Magno de Almeida wrote:
 
Então o compilador pode implementar desta forma:

x = ++y,++x;


Este compilador não está respeitando o "sequence point" introduzido pela vírgula, e portanto é defeituoso.

--
 P.

Adriano dos Santos Fernandes

unread,
Feb 11, 2011, 8:38:59 AM2/11/11
to ccppb...@googlegroups.com
Fazendo uma corre��o, mas a id�ia de testar o que seria UB permanece...

char c[2] = {0, 0};
char* x = c;

*x = (++x, 1);

Felipe Magno de Almeida

unread,
Feb 11, 2011, 8:45:10 AM2/11/11
to ccppb...@googlegroups.com
2011/2/11 P. <pedro....@ccppbrasil.org>:

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.

Felipe Magno de Almeida

unread,
Mar 9, 2011, 5:39:52 PM3/9/11
to ccppb...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages