Re: lug-bg: c/cpp incr/decr
- Subject: Re: lug-bg: c/cpp incr/decr
- From: vladev@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (Valeri Vladev)
- Date: Wed, 19 Jan 2005 13:31:04 +0200
- Mail-followup-to: vladev@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, lug-bg@xxxxxxxxxxxxxxxxxx
On Tue, 18 Jan 2005, Peter Pentchev wrote:
> Явно поне при GCC се използва parser, който се опитва първо да навлезе в
> дълбочина, т.е. да намери най-дългото възможно съвпадение с валиден терм,
> така че поредицата от плюсове в 'a+++b' бива разбита първо на '++', защото
> е по-дълго.
>
> Ще се поровя да видя дали не мога да намеря някъде някакъв истински
> стандарт, който да дефинира това поведение, или пък ще си остане undefined
> behavior.
>
> Поздрави,
> Петър
>
> --
> Peter Pentchev roam@xxxxxxxxxxx roam@xxxxxxxx roam@xxxxxxxxxxx
> PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
> Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553
> If you think this sentence is confusing, then change one pig.
Изразите се парсват като трябва. Проблема е другаде.
Накарах компилатора да ми изкара асемблирския код и всичко стана
ясно.
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" нямам представа кой би си помислил да
използва,
но ако е семантично верен трябва да дава верен резултат.
--
Valeri Vladev <tolio@xxxxxxxxxxx>
PGP-Key-ID: 0x9CB166CD ICQ #235683218
Registered Linux User #362712
/********** **********/
============================================================================
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
============================================================================
|