PDA

View Full Version : How is it evaluvated?


Lloyd
08-01-2006, 02:11 PM
#include<stdio.h>
int main()
{
int a=0,b=0,c=0;
c=++a + (++b + ++a) + ++b;
printf("\n%d%d%d",a,b,c);
c=++a + ++a + ++a;
printf("\n%d%d%d",a,b,c);
return 0;
}


outputs are
227
307
Could you please explain how these expressions are evaluated?

Thanks and Regards,
Lloyd

thinking
08-02-2006, 10:58 AM
;-)
first, i think the code you gave should look like this:

#include<stdio.h>
int main()
{
int a=0,b=0,c=0;
c=++a + (++b + ++a) + ++b;
printf("\n%d%d%d",a,b,c);
a=b=c=0;
c=++a + ++a + ++a;
printf("\n%d%d%d",a,b,c);
return 0;
}

it took a bit to understand but i think it works this way:
the first line
c=++a + (++b + ++a) + ++b;
evaluates like this:
first a = 0 and b = 0
then a gets incremented
a = 1
then b gets incremented
b = 1
a gets incremented
a = 2
NOW it looks like this:
2 + (1+2) + 1
now (1+2) is calculated = 3
b gets incremented
2 + 3 + 2 = 7

the second one:
c=++a + ++a + ++a;
first a = 0 and c = 0
a gets incremented
a = 1
a gets incremented
a = 2
we have: 2 + 2 + 2
the first two a's are summed up
we have: 4 + 2
a gets incremented
we have: 4 + 3
result: 7

i don't really understand why it works this way
altough it sounds pretty simple to me

how do i know how it works:
first make the prog a bit simpler easier for example:

#include<stdio.h>
int main()
{
int a=0,b=0,c=0;
c=++a + (++b + ++a) + ++b;
return 0;
}



now compile this with -S option, like:
gcc -S -o test.o test.c
now you have the assembler code in test.o
which looks like this:

.file "test.c"
.text
.globl main
.type main, @function
main:
.LFB3:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl $0, -4(%rbp)
movl $0, -8(%rbp)
movl $0, -12(%rbp)
leaq -4(%rbp), %rax
incl (%rax)
leaq -8(%rbp), %rax
incl (%rax)
leaq -4(%rbp), %rax
incl (%rax)
movl -4(%rbp), %eax
addl -8(%rbp), %eax
movl %eax, %edx
addl -4(%rbp), %edx
leaq -8(%rbp), %rax
incl (%rax)
movl %edx, %eax
addl -8(%rbp), %eax
movl %eax, -12(%rbp)
movl $0, %eax
leave
ret
.LFE3:
.size main, .-main
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string ""
.uleb128 0x1
.sleb128 -8
.byte 0x10
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.quad .LFB3
.quad .LFE3-.LFB3
.byte 0x4
.long .LCFI0-.LFB3
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE1:
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.3.3 (SuSE Linux)"


the interesting part is this:

.LCFI1:
movl $0, -4(%rbp)
movl $0, -8(%rbp)
movl $0, -12(%rbp)
leaq -4(%rbp), %rax
incl (%rax)
leaq -8(%rbp), %rax
incl (%rax)
leaq -4(%rbp), %rax
incl (%rax)
movl -4(%rbp), %eax
addl -8(%rbp), %eax
movl %eax, %edx
addl -4(%rbp), %edx
leaq -8(%rbp), %rax
incl (%rax)
movl %edx, %eax
addl -8(%rbp), %eax
movl %eax, -12(%rbp)
movl $0, %eax
leave
ret


but since i'm not good in assembler i'm not sure if i understood it correctly, but:
1. set a,b,c to zero
movl $0, -4(%rbp)
movl $0, -8(%rbp)
movl $0, -12(%rbp)
2. increment a
leaq -4(%rbp), %rax
incl (%rax)
3. increment b
leaq -8(%rbp), %rax
incl (%rax)
4. increment a
leaq -4(%rbp), %rax
incl (%rax)
at this point we have b = 1 and a = 2
5. save a in eax and add b to eax --> eax = 3
movl -4(%rbp), %eax //// this is (++b + ++a)
addl -8(%rbp), %eax
6. save eax to edx and add a to edx --> edx = 3+2 = 5
movl %eax, %edx // this is ++a + (3)
addl -4(%rbp), %edx
7. increment b --> b = 2
leaq -8(%rbp), %rax
incl (%rax)
8. move edx to eax --> eax = 5
movl %edx, %eax
9. add b to eax --> eax = 5 + 2 = 7
addl -8(%rbp), %eax
10. save eax to c --> c = 7
movl %eax, -12(%rbp)

try
c = ++a + ++a + ++a;
for yourself

greetz

i3839
08-02-2006, 09:53 PM
Nothing betters to waste your time on guys? Code where it's unclear how it will be evaluated is just uninteresting bad code.

Lloyd
08-03-2006, 04:55 AM
Sorry I3839, I just meant it for learning only. Ofcourse it is a bad code, It may help us to understand C better. Thanks "thinking " for your effort.

Thanks and Regards,
Lloyd.

i3839
08-03-2006, 10:02 AM
It's all right, only slightly amusing. ;-)

Thinking's answer was a very thorough one though, very impressive.

Just what I get with gcc 4.1.1 and warnings turned on:


cc -O2 -s -Wall -W -pipe -s t.c -o t
t.c: In function 'main':
t.c:7: warning: operation on 'b' may be undefined
t.c:7: warning: operation on 'a' may be undefined
t.c:10: warning: operation on 'a' may be undefined
t.c:10: warning: operation on 'a' may be undefined
tmp $ ./t

227
5213