David C. Rankin wrote:
On 05/14/2012 03:04 PM, Cristian Rodríguez wrote:
El 14/05/12 14:59, David C. Rankin escribió:
On 05/11/2012 05:10 PM, Cristian Rodríguez wrote:
El 11/05/12 15:06, David C. Rankin escribió:
All seem to do the same thing??
Please read www.akkadia.org/drepper/dsohowto.pdf section 2.4 to know the difference.
Oops, sorry Christian -- you will get 2 -- forgot to change the address...
Grr... Thank you! If I understood what I read, then for the benefit of those that didn't read it:
char *str = "foo"; and char str[] = "foo";
are NOT the same thing. The meaningful difference, according to Drepper, being that the first declaration creates a variable named 'str' with its initial value being a 'pointer to' the string "foo". This requires the use of a variable in the non-sharable data segment and a relocation to initialize it with the pointer.
The second declaration of char str[] = "foo"; simply creates a name for the sequence of bytes that initially contain "foo". The name for the sequence of bytes is not variable and cannot change, it is 'str' forever. Of course the bytes pointed to by 'str' can change.
That is all new to me. Thank you Christian. When given the option to initialize with char *str or char str[], it shall be char str[] from now on.
I spent a semester writing in C, but debugging the same code at the assembly language level, and your interpretation is correct. Lets look at what the assembler puts out from a sample input file stringtest.c: 1 char *str1 = "foo"; 2 char str2[]= "bar"; 3 main() 4 { 5 char *str3 = "first_local"; 6 char str[] = "second_local"; 7 } gcc -S stringtest.c produced the following 32-bit 80x86 assembler file Original .s file has no # comments. All comments are mine. Lines with ## are ones I have inserted for clarification. Lines with ##>> are ones I have inserted with the C source code I have inserted #----- lines for readability key: # comment .THISISALABEL: #another comment THISISALABELTOO: .assemblerdirective [argument] .file "stringtest.c" ##>> 1 char *str1 = "foo"; .globl str1 # begin working on global variable str1 ## ---- first allocate a string of characters .section .rodata # mark this area as READ ONLY data .LC0: # insert generic label in address to mark first string's location .string "foo" # characters 'f' 'o' 'o' '\0' placed in memory image #----------------------------------------- .data # end readonly section, begin mutable data .align 4 # make sure next label is aligned on a 4-byte boundary .type str1, @object # str1 is the label of a variable. .size str1, 4 # 4 bytes reserved (32-bit pointer) for str1 ## 4th byte is the terminating '\0' character. ## -- str1: # label for first declared variable, str1 in address .long .LC0 # str1 initialized with address of generic label LC0 # i.e. str1 = points to 'f' 'o' 'o' '\0' allocated above ## -------------------------------------------------------------------------------------- ##>> 2 char str2[]= "fubar"; .globl stri2 # begin working on global variable stri2 .type stri2, @object # stri2 is the label of a variable .size stri2, 6 # 6 bytes reserved for stri2 stri2: # label for 2nd global variable, stri2, at start # of the 6-byte block .string "fubar" # which is filled with 'f' 'u' 'b' 'a' 'r' '\0' ##-------------------------------------------------------------------------------- .section .rodata # start READ ONLY data section. .LC1: # generic label for 3rd string location .string "first_local" # 17 chars 'f' 'i' 'r' .... 'c' 'a' 'l' '\0' ##>> 3 main () .text # now generating executable code .globl main # main is a label with global scope .type main, @function # main is a function main: # locate label main in the address space ##>> 4 { .LFB0: # locate LFB0 (Label Function Begin 0) in address space. .cfi_startproc # Begin standard gcc function preamble pushl %ebp # standard gcc function preamble .cfi_def_cfa_offset 8 # standard gcc function preamble .cfi_offset 5, -8 # standard gcc function preamble movl %esp, %ebp # standard gcc function preamble .cfi_def_cfa_register 5 # standard gcc function preamble subl $32, %esp # last line of standard function preamble ##note ebp is as the frame-pointer. Local variables are allocated in the function's frame. ## all local variables are addressed as offset(%ebp). Note that frame grows downward. ## 5 char *string3 = "first_local"; movl $.LC1, -4(%ebp) # initialize mem:(ebp-4)~(ebp-7) to point at LC1 ## remember LC1 is in a read-only block. ## 6 char string4 = "second_local"; ## string4 located at mem:(ebp-17), ends at mem:(ebp-5) movl $1868785011, -17(%ebp) # mem:(ebp-17)~(ebp-14) with 's' 'e' 'c' 'o' movl $1818190958, -13(%ebp) # mem:(ebp-13)~(ebp-10) with 'n' 'd' '_' 'l' movl $1818321775, -9(%ebp) # mem:(ebp-9 )~(ebp-6 ) with 'o' 'c' 'a' 'l' movb $0, -5(%ebp) # mem:(ebp-5)='\0' ## 7 } leave .cfi_restore 5 # standard end of function produced by gcc .cfi_def_cfa 4, 4 # standard end of function produced by gcc ret # standard end of function produced by gcc .cfi_endproc # standard end of function produced by gcc .LFE0: # Label Function End 0 ## --------- appendix of stuff added by GCC and SUSE ---------- .size main, .-main .ident "GCC: (SUSE Linux) 4.6.2" .section .comment.SUSE.OPTs,"MS",@progbits,1 .string "ospwg" .section .note.GNU-stack,"",@progbits -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org