Linux-Bulgaria.ORG
навигация

 

начало

пощенски списък

архив на групата

семинари ...

документи

как да ...

 

 

Предишно писмо Следващо писмо Предишно по тема Следващо по тема По Дата По тема (thread)

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



 

наши приятели

 

линукс за българи
http://linux-bg.org

FSA-BG
http://fsa-bg.org

OpenFest
http://openfest.org

FreeBSD BG
http://bg-freebsd.org

KDE-BG
http://kde.fsa-bg.org/

Gnome-BG
http://gnome.cult.bg/

проект OpenFMI
http://openfmi.net

NetField Forum
http://netField.ludost.net/forum/

 

 

Linux-Bulgaria.ORG

Mailing list messages are © Copyright their authors.