As I noted in my previous message, the right hand side must be evaluated
before the assignment can occur. I have added comments to the assembly
language below to show how this occurs....
On 08/27/2011 05:57 PM, uulinux wrote:
Dear Maciej:
Thanks very mach. I am so glad to get a replay. I seem to know what
you mean. The auto variable allocated from stack, whose value is
initialized by code in runtime, not by compiler.
But look the assembler code compiled by gcc-4.4.5.
=========================================================
.file "main.c"
.section .rodata
.LC0:
.string "\t%d"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $48, %esp # allocate space for array on stack
movl 32(%esp), %eax # fetch value in a[2] (which has not
yet been initialized)
movl 24(%esp), %ecx # fetch value in a[0] (which has not
yet been initialized)
movl 28(%esp), %edx # fetch value in a[1] (which has not
yet been initialized)
leal (%ecx,%edx), %edx # compute a[0] + a[1] (meaningless
value)
# Now the necessary arithmetic has been completed to evaluate the right
hand side. The other three values are literals.
movl $1, 24(%esp) # a[0] = 1 (literal value, so no
fetching or computation needed)
movl $2, 28(%esp) # a[1] = 2 (literal value, so no
fetching or computation needed)
movl $3, 32(%esp) # a[2] = 3 (literal value, so no
fetching or computation needed)
movl %eax, 36(%esp) # a[3] = a[2] (previously computed
above]
movl %edx, 40(%esp) # a[4] = a[0] + a[1] (previously
computed above]
movl $0, 44(%esp) # a[5] = 0
movl $0, 44(%esp) # a[5] = 0
# I have no idea why 0 is stored beyond the end of the array or why it
is done twice. But the
# assignment to the elements of the array occur as I have always
expected in C.
jmp .L2
.L3:
movl 44(%esp), %eax
movl 24(%esp,%eax,4), %edx
movl $.LC0, %eax
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
addl $1, 44(%esp)
.L2:
cmpl $4, 44(%esp)
jle .L3
movl $10, (%esp)
call putchar
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (Gentoo 4.4.5 p1.2, pie-0.4.5) 4.4.5"
.section .note.GNU-stack,"",@progbits
=========================================================
Please notice this code compiled from "int a[5] = [1, 2, 3, a[2],
a[0]+a[1]]":
movl $1, 24(%esp)
movl $2, 28(%esp)
movl $3, 32(%esp)
movl %eax, 36(%esp)
movl %edx, 40(%esp)
I just doubt whether there is something wrong or not very good. I
expect code as following:
movl $1, 24(%esp)
movl $2, 28(%esp)
movl $3, 32(%esp)
movl 32(%esp), %eax
movl %eax, 36(%esp)
movl 24(%esp), %edx
movl 28(%esp), %eax
leal (%edx,%eax), %eax
movl %eax, 40(%esp)
And I expect "int a[5] = [1, 2, 3, a[2], a[0]+a[1]]" is equivalent to:
int a[5] = [1, 2, 3];
a[3] = a[2];
a[4] = a[0]+a[1];
If the array is global variable and which will be put in .data
segment by compiler, gcc-4.4.5 will report error as following. But I
think this kind method of initialization is useful.
=========================================================
localhost array # gcc -o main main.c
main.c:28: error: initializer element is not constant
main.c:28: error: (near initialization for 'a[3]')
main.c:28: error: initializer element is not constant
main.c:28: error: (near initialization for 'a[4]')
=========================================================