Re: lug-bg: c/cpp incr/decr
- Subject: Re: lug-bg: c/cpp incr/decr
- From: George Danchev <danchev@xxxxxxxxx>
- Date: Thu, 20 Jan 2005 23:15:53 +0200
On Wednesday 19 January 2005 13:31, Valeri Vladev wrote:
-кръц-
> Изразите се парсват като трябва. Проблема е другаде.
> Накарах компилатора да ми изкара асемблирския код и всичко стана
> ясно.
> gcc version 3.3.4 (Debian 1:3.3.4-6sarge1)
> gcc -S 1.c
>
> #include <stdio.h>
> int
> main (void)
> {
> register int x = 0;
> register int a = 0;
> x = x++ + (++x + a);
> printf("(x = x++ + ++x) x = %d\n",x);
> x = 0;
> a = x++ + ++x;
> printf("(a = x++ + ++x) a = %d\n",a);
> printf("x = %d\n",x);
> return (0);
> }
> Сложих още една променлива "а" за да го объркам малко.
> Иначе такъв код прави, че аз се обърквам.
> Изчислява израза от дясно на ляво, но:
>
>
> x = x++ + (++x + a);
> movl $0, -4(%ebp) ;х = 0
> movl $0, -8(%ebp) ;а = 0
> incl -4(%ebp) ;изчислява ++х
> movl -4(%ebp), %edx ;х вече 1 отива в edx
> addl -8(%ebp), %edx ;прибавя "а" към edx, edx = (++x + a) = 1
> movl -4(%ebp), %eax ;х отива в eax = 1
> addl %edx, %eax ;прибавя edx = (++x + a) = 1 към eax = x = 1
> ;eax = 2 което е и верния отговор
> ;сега би трябвало да си довърши работата х++
> ;и тогава да присвои резултата eax на х но!
> movl %eax, -4(%ebp) ;резултата се присвоява на х, x = 2
> incl -4(%ebp) ;и тогава се изпълнява х++ , x = 3
всичко това е много хубаво ;-) , но аз бих те попитал защо след като смяташ
x = x++ + (++x + a); или x = x++ + ++x; (все тая) и a=x=0;
и имаш x++ (в дясната страна) тогава резултата след завършване на израза не е
ти се получава 1 ? Аз ще отчета само x++ (че е инкремент на x след израза) и
съм готов с отговора ;-) няма защо да натрупвам резултата от сметките... (za
tfa компила с -Wall казва недефинирано поведение с което ще се съгласят и в
древна Елада ;-)
напиши го като a = b++ + ++c, дай им нули на всичките и ще получиш единица
както и да го смяташ ;-) , т.е. в резултата от израза участва само един
инкремент.
Ето още един лек пример:
*уж викаме еф с два аргумента i, но формалните параметри разделят разботата в
две променливи, джам ;-)
*на пръв поглед всичко е ток и жица, но в последния printf израза не е
завършен че да покажем стойностите на p и q без значение в къф ред ще
събираме, ръгаме в скоби и т.н) - няма какво да принтираме и за трите
%d-та...
*преди предпоследния printf израза е завършен и е ясно какво ще принтиме.
#include <stdio.h>
void f(int p, int q );
int main(void)
{
int i=0;
printf("that's not a i++ + ++i collision\n");
f(i, i);
return 0;
}
void f(int p, int q)
{
int a=0 ;
p = 3 ;
q = 4 ;
/* tfa e ok */
printf("p++ + ++q = %d\n", p++ + ++q );
printf("p = %d, %d\n", p, q );
/* tfa e ok */
printf("p++ + ++q = %d\n", p++ + ++q );
/* tfa e ok */
a = p++ + ++q;
printf("p++ + ++q = %d\n, p = %d\n, q = %d\n", a , p, q );
/* tfa e undefined, dont try that at home! */
printf("p = %d\n, q = %d\n, p++ + ++q = %d\n", p, q, p++ + ++q );
}
> Проблима е, че ползва за променливата от ляво и това което изчислява
> дясно една и съща памет! Сигурно е някаква оптимизация защото
> променливата е една и съща.
няма как компилатора да използва временна променлива за стойност която искаш
хем да участва преди да е инкрементирана в израза, хем след като е
инкрементирана да участва в израза и накрая този резултат да не противоречи
на следствието от пост-инкрементирането (x++, което участва в израза). Това е
математически невъзможно/недефинирано ;-)
> Ако при изчисляването на израза се използва временна променлива
> всичко щеше да е ОК.
> Такъв израз "x = x++ + ++x" нямам представа кой би си помислил да
> използва
в този точно вид не (x = x++ + ++x), но може инцидентно да достигнеш до такова
животно (без да искаш;) ... А иначе c = a++ + ++b е окай отсекъде, което може
би се е имало в предвид. Т.е. с един израз да получим
сбора от двете плюс единица (a+b+1) и всяко поотделно увеличено е единица (a+1
и b+1 ... да се пишат 3 израза е грубо ;-)
(Да, онова за въжето го знаем ;-)
> но ако е семантично верен трябва да дава верен резултат.
Семантично е неверен (виж горе)
т.е., след операция от вида x = x++ + ++ x, кое ще е стойността на x, това
което се е натрупало от изчислението или просто следствието от x++ което е x
+1 след изчисляване на израза, да но след изчислението на израза имаме друго
натрупване като резултат.... Та не мой така механично да се счита ;-)
--
pub 4096R/0E4BD0AB 2003-03-18 <danchev.fccf.net/key pgp.mit.edu>
fingerprint 1AE7 7C66 0A26 5BFF DF22 5D55 1C57 0C89 0E4B D0AB
============================================================================
A mail-list of Linux Users Group - Bulgaria (bulgarian linuxers).
http://www.linux-bulgaria.org - Hosted by Internet Group Ltd. - Stara Zagora
To unsubscribe: http://www.linux-bulgaria.org/public/mail_list.html
============================================================================
|