about arrays initialization

uulinux uulinux@gmail.com
Sun Aug 28 08:07:00 GMT 2011


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]')
>> =========================================================
>



More information about the Gcc-help mailing list