Re: about arrays initialization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Bob plantz:

Thank you very mach. You are very enthusiastic and friendly, and your analysis is very good. The C code is as following:
===============================================
        #include   <stdio.h>
        int main()
        {
                int a[5]={1, 2, 3, a[2], a[0]+a[1]};
                int i=0;

                for (i=0; i<5; i++) {
                        printf("\t%d", a[i]);
                }
                return 0;
        }
===============================================
   So, please read the following again.
>> 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. It is not a[5] = 0. It is i=0; But I also have no idea about why it is done twice.

I have known the reason of this issue is "a[3], a[4]" has not evaluated before the assignment occurred. So the result of this action is not fixed? And the result of this action is determined by the compiler. But there is still a question in my head. Why gcc put "a[3]=a[2]; a[4]=a[0]+a[1];" operation in the front of "a[0]=1; a[1]=2; a[2]=3;"? Is not the array has initialized from a[0] to a[n]? I just wonder why not put "a[0]=1; a[1]=2; a[2]=3;" operation in the front of "a[3]=a[2]; a[4]=a[0]+a[1];".

Is there a method to achieve “a[3] = a[2]; a[4]=a[0]+a[1]” for global variable. So, I just need to update the value of a[0]…a[1] when the value should be changed. I think it is useful when the arithmetic expression is very complex. The value of some elements in a array will be auto updated by compiler, just like this:
===============================================
static int a[6]={1, 2, 3, a[2], a[0]+a[1], sin(a[4])}; // gcc-4.4.5 report error !

        #include   <stdio.h>
        int main()
        {
                int i=0;

                for (i=0; i<6; i++) {
                        printf("\t%d", a[i]);
                }
                return 0;
        }
===============================================

于 2011/8/28 上午 10:20, Bob Plantz 写道:
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]')
=========================================================



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux