gcc Откачи?!?

4 views
Skip to first unread message

Daniel_10b

unread,
Dec 1, 2011, 2:43:03 PM12/1/11
to ТУЕС Програмно осигуряване 2011
#include <stdio.h>
int x=3;
int main()
{
x = (x++)+(++x) ;
printf("%d\n",x);
printf("%d\n",++x);
printf("%d\n",x++);
return 0;
}
Може ли някой да пробва това и да каже изхода.На мен ми е:
4
5
5
?!?

Viktor Nonov

unread,
Dec 1, 2011, 4:00:39 PM12/1/11
to cprogrammi...@googlegroups.com
Здравей Даниел,

Наистина този случай е интересен, но е напълно логичен.
Когато имаш x++ се съхранява текущата стойност на променливата x и се запомня, че след като statement-а завърши тази стойност трябва да се увеличи с 1 и да се присвои на x.
Какво се случва всъщност в израза: x = (x++) + (++x);. Първо се запомня текущата стойност на x, която е 3 и също, че след като завърши statement-a тази стойност трябва да се увеличи с 1 и да се присвои на x. Израза придобива вида x = 3 + (++x). След това при (++x) се извършва инкрементиране и присвояване на x (++x)=4. Изразът придобива вида x = 3 + 4. Което е x = 7. В крайна сметка стойността на израза е 7. Тук идва ролята на точката и запетайката - ;. Когато тя бъде срещната се инкрементира по-рано запомнената стойност на х тоест 3 и се присвоява на х. И затова x има стойност 4 в първия printf();

Поздрави,
Виктор

2011/12/1 Daniel_10b <daniel.g...@gmail.com>

daniel georgiev

unread,
Dec 1, 2011, 4:09:38 PM12/1/11
to cprogrammi...@googlegroups.com
нещо не ми стана ясно...много се засука всичко :D

2011/12/1 Viktor Nonov <vno...@elsys-bg.org>

Viktor Nonov

unread,
Dec 1, 2011, 4:15:27 PM12/1/11
to cprogrammi...@googlegroups.com
Идеята е, че като се срещне x++ се взима текущатата му стойност (нека означим стойността с y) и след като се срещне ; тази текуща стойност y се увеличава с 1 и се прави x = y.

2011/12/1 daniel georgiev <daniel.g...@gmail.com>

Lubomir Tzvetkov

unread,
Dec 2, 2011, 3:22:21 AM12/2/11
to cprogrammi...@googlegroups.com
Здравей,
Набързо го погледнах и разликата идва в това дали променливата си я декларирал като глобална или локална. Да ти кажа честно и идея си нямам в момента, защо прави така!
Като е глобална става на 4, а като е локална на 9. Ще го погледна по-обстойно събота и неделя.

Поздрави, Любо.

Lubomir Tzvetkov

unread,
Dec 2, 2011, 3:44:18 AM12/2/11
to cprogrammi...@googlegroups.com
Здравейте,
Компилирах ги до асемблерски команди и има голяма разлика дали променливата е локална или глобална, ще го питам Камбарев, че той е по-наясно с тези неща. Пращам ви да ги разгледате. : )
Напълно възможно да е някакъв бъг - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17282. Ето подобно нещо.

Поздрави, Любо.
bug.rar

hris...@abv.bg

unread,
Dec 2, 2011, 9:16:02 AM12/2/11
to ТУЕС Програмно осигуряване 2011
При компилация на кода с Dev C++ резултатите са:
9
10
10
Явно бъга си е само за gcc-то

On 2 дек, 10:44, Lubomir Tzvetkov <lubo.tzvet...@gmail.com> wrote:
> Здравейте,
> Компилирах ги до асемблерски команди и има голяма разлика дали променливата
> е локална или глобална, ще го питам Камбарев, че той е по-наясно с тези
> неща. Пращам ви да ги разгледате. : )

> Напълно възможно да е някакъв бъг -http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17282. Ето подобно нещо.
>
> Поздрави, Любо.
>
>  bug.rar
> 1KПрегледИзтегляне

Lubomir Tzvetkov

unread,
Dec 2, 2011, 9:13:03 AM12/2/11
to cprogrammi...@googlegroups.com
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫,
О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫. О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫ : ).

О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫.

Daniel_10b

unread,
Dec 2, 2011, 12:10:31 PM12/2/11
to ТУЕС Програмно осигуряване 2011
_main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp call
___main movl _x, %eax addl $2, %eax movl %eax, _x movl %eax, 4(%esp)
movl $LC0, (%esp) call _printf xorl %eax, %eax leave ret.globl
_x .data .align 4_x: .long 3 .def _printf; .scl 2; .type 32; .endef

Ми то и от асемблера се вижда, че има грешка:
първо: %eax =_x
после: %eax =_x +2
_x = _x+2 -това не трябва да е така принципно.
movl $LC0, (%esp) - това бута стойността за извикване на printf май в
стека.
май х се променя само с еденица, т.е. само постфикса се изпълнява...


On 2 дек, 10:44, Lubomir Tzvetkov <lubo.tzvet...@gmail.com> wrote:

> Здравейте,
> Компилирах ги до асемблерски команди и има голяма разлика дали променливата
> е локална или глобална, ще го питам Камбарев, че той е по-наясно с тези
> неща. Пращам ви да ги разгледате. : )

> Напълно възможно да е някакъв бъг -http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17282. Ето подобно нещо.
>
> Поздрави, Любо.
>
>  bug.rar
> 1KПрегледИзтегляне

Lubomir Tzvetkov

unread,
Dec 2, 2011, 1:15:40 PM12/2/11
to cprogrammi...@googlegroups.com
Здрасти Даниеле,
Най-ясно може да се види при тази част асемблерски код. Тя отговаря на:

****     x = x++ + ++x;

mov eax, DWORD PTR _x  // _x = 3 в началото, то се записва в регистър eax
mov edx, DWORD PTR _x  //_x = 3 в началото, то се записва в регистър edx
inc edx                            // инкрементира с 1 edx => edx = 4
mov DWORD PTR _x, edx  // записва edx в _x => _x = 4
mov edx, DWORD PTR _x  // записва _x в edx
add edx, eax                     // прибавя eax към edx => edx = 7
mov DWORD PTR _x, edx  // прибавя edx към _x => _x = 7
inc eax                            // инкрементира eax => eax = 4
mov DWORD PTR _x, eax  // записва eax в _x => _x = 4

Можеш да си направиш вкъщи същото като напишеш:
gcc -g -Wa,-adhln -masm=intel bug.c>bug.asm

Това ти генерира асемблерски код съответстващ на определен ред от твоя сорс код. Много е удобно и страшно лесно се разглеждат различните команди в C преведени на асемблер какво правят.

Така като прочетох имаш явно два синтакса:
http://asm.sourceforge.net/articles/linasm.html

-masm=intel - така определяш в какъв синтаксис да ти компилира файла.

Поздрави, Любо.

Viktor Nonov

unread,
Dec 3, 2011, 5:17:30 AM12/3/11
to cprogrammi...@googlegroups.com
Здравейте,

Това с асемблерския код наистина е хитро и полезно.
Тъй като аз съм срещал този проблем и в друг език. Не съм го смятал като бъг.
Важното в случая е да се запомни, че в когато пишете програма този запис:

x = x++ + ++x
е признак за много лош стил на писане. Придържайте се към максимално простите statement-и

Поздрави,
Виктор

2011/12/2 Lubomir Tzvetkov <lubo.t...@gmail.com>

TriEdgeAI

unread,
Dec 3, 2011, 3:33:38 PM12/3/11
to ТУЕС Програмно осигуряване 2011
Dev-C++ не използваше ли също gcc?

Lubomir Tzvetkov

unread,
Dec 3, 2011, 3:50:42 PM12/3/11
to cprogrammi...@googlegroups.com
Викторе,
Това го имаше на контролното : ). Съответно дадено от нас : ).

Поздрави, Любо.
Reply all
Reply to author
Forward
0 new messages