c - Global variable vs macro expansion for string literal -


i'm trying understand of intricacies preprocessor , of c compiler (specifically, gnu gcc) , string literals. more efficient assign global variable string literal occupies 1 place in memory vs using #define preprocessor directive?

as in example, string literal on place in memory , accessed several times:

#include <stdio.h> #include <string.h> char output[20] = "hello, world!!!"; int main (){     printf("%s %d characters long.\n", output, strlen(output));     return 0; } 

vs doing preprocessor:

#include <stdio.h> #include <string.h> #define output "hello, world!!!"  int main (){     printf("%s %d characters long.\n", output, (int) strlen(output));     return 0; } 

which translates as:

#include <stdio.h> #include <string.h> #define output "hello, world!!!"  int main (){     printf("%s %d characters long.\n", "hello, world!!!", (int) strlen("hello, world!!!"));     return 0; } 

what i'm asking in last 2 examples example using preprocessor, compiler have 2 separate instances of "hello, world!!!" in 2 separate memory locations or compiler smart enough make 1 memory location?

if 2 separate memory locations, isn't more resource-friendly use global variable rather macro expansion program constants?

your compiler should smart enough store 1 instance of string. can verify checking assembly outputs programs.

for example, using gcc:

assume first example called "global.c".

gcc -wall -s global.c  .file   "global.c" .globl  output .data .align 16 .type   output, @object .size   output, 20 output: .string "hello, world!!!" .zero   4 .section    .rodata .lc0: .string "%s %d characters long.\n" .text .globl  main .type   main, @function main:  // more code... 

assume preprocessor example called "preproc.c".

gcc -wall -s preproc.c .file   "preproc.c" .section    .rodata .lc0: .string "%s %d characters long.\n" .lc1: .string "hello, world!!!" .text .globl  main .type   main, @function main: // more code... 

in both cases, 1 copy of "hello, world!!!" , "%s %d characters long.\n" exist. in first example, have save space 20 characters because code has modifiable array. if changed this

char output[20] = "hello, world!!!"; 

to

const char * const output = "hello, world!!!"; 

you get:

.file   "global.c" .globl  output .section    .rodata .lc0: .string "hello, world!!!" .align 8 .type   output, @object .size   output, 8 output: .quad   .lc0 .lc1: .string "%s %d characters long.\n" .text .globl  main .type   main, @function main: // more code... 

now saving space pointer , string.

which way better negligible in situation, though recommend using preprocessor scope of strings stays within main function.

both emit identical code optimizations.

global.c (const char * const output):

gcc -wall -o3 -s global.c  .file   "global.c" .section    .rodata.str1.1,"ams",@progbits,1 .lc0: .string "hello, world!!!" .lc1: .string "%s %d characters long.\n" .section    .text.startup,"ax",@progbits .p2align 4,,15 .globl  main .type   main, @function main: .lfb44: .cfi_startproc subq    $8, %rsp .cfi_def_cfa_offset 16 movl    $15, %ecx movl    $.lc0, %edx movl    $.lc1, %esi movl    $1, %edi xorl    %eax, %eax call    __printf_chk xorl    %eax, %eax addq    $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .lfe44: .size   main, .-main .globl  output .section    .rodata .align 8 .type   output, @object .size   output, 8 output: .quad   .lc0 .ident  "gcc: (ubuntu/linaro 4.6.3-1ubuntu5) 4.6.3" .section    .note.gnu-stack,"",@progbits 

preproc.c

gcc -wall -o3 -s preproc.c      .file   "preproc.c" .section    .rodata.str1.1,"ams",@progbits,1 .lc0: .string "hello, world!!!" .lc1: .string "%s %d characters long.\n" .section    .text.startup,"ax",@progbits .p2align 4,,15 .globl  main .type   main, @function main: .lfb44: .cfi_startproc subq    $8, %rsp .cfi_def_cfa_offset 16 movl    $15, %ecx movl    $.lc0, %edx movl    $.lc1, %esi movl    $1, %edi xorl    %eax, %eax call    __printf_chk xorl    %eax, %eax addq    $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .lfe44: .size   main, .-main .ident  "gcc: (ubuntu/linaro 4.6.3-1ubuntu5) 4.6.3" .section    .note.gnu-stack,"",@progbits 

looking @ both main functions, can see instructions identical.


Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

javascript - jQuery .height() return 0 when visible but non-0 when hidden -