javascript - Hoisting/Reordering in C, C++ and Java: Must variable declarations always be on top in a context? -


i read little hoisting , reordering, seems java vm may choose hoist expressions. read hoisting of function declarations in javascript.

first question: can confirm if hoisting exist in c, c++ , java? or compiler/optimization dependent?

i read lot of example c codes put variable declarations on top, before assert or boundary condition. thought little faster asserts , boundary cases before variable declarations given function terminate.

main question: must variable declarations on top in context? (is there hoisting @ work here?) or compiler automatically optimize code checking these independent asserts , boundary cases first (before irrelevant variable declaration)?

here's related example:

void mergesort(struct node** headref) {     struct node* a;     struct node* b;     if ((*headref == null) || ((*headref)->next == null)) {         return;     }     frontbacksplit(*headref, &a, &b);     mergesort(&a);     mergesort(&b);     *headref = sortedmerge(a, b); } 

as shown above, boundary case not depend on variables "a" , "b". thus, putting boundary case above variable declarations make faster?


updates:

the above example isn't hoped because variables "a" , "b" declared, not initialized there. compiler ignore declaration until need use them.

i checked gnu gcc assemblies variable declarations initializations, assemblies have different execution sequence. compiler did not change ordering of independent asserts , boundary cases. so, reordering these asserts , boundary cases change assemblies, changing how machine runs them.

i suppose difference minuscule people never cared this.

the compiler may reorder/modify code wishes, long modified code equivalent original if executed sequentially. hoisting allowed, not required. optimization , compiler specific.

variable declarations in c++ can wherever wish. in c used have on top in context, when c99 standard introduced, rules relaxed , can wherever want, c++. still, many c programmers stick putting them on top in context.

in example, compiler free move if statements top, don't think would. these variables pointers declared on stack , un-initialized, cost of declaring them minimal, might more efficient create them @ beginning of function, rather after asserts.

if declarations involve side-effects, example

struct node *a = some_function(); 

then compiler limited in can reorder.

edit:

i checked gcc's loop hoisting in practice short program:

#include <stdio.h> int main(int argc, char **argv) {     int dummy = 2 * argc;     int = 1;     while (i<=10 && dummy != 4)         printf("%d\n", i++);     return 0; } 

i've compiled command:

gcc -std=c99 -pedantic test.c -s -o test.asm 

this output:

    .file   "test.c"     .def    ___main;    .scl    2;  .type   32; .endef     .section .rdata,"dr" lc0:     .ascii "%d\12\0"     .text     .globl  _main     .def    _main;  .scl    2;  .type   32; .endef _main: lfb7:     .cfi_startproc     pushl   %ebp     .cfi_def_cfa_offset 8     .cfi_offset 5, -8     movl    %esp, %ebp     .cfi_def_cfa_register 5     andl    $-16, %esp     subl    $32, %esp     call    ___main     movl    8(%ebp), %eax     addl    %eax, %eax     movl    %eax, 24(%esp)     movl    $1, 28(%esp)     jmp l2 l4:     movl    28(%esp), %eax     leal    1(%eax), %edx     movl    %edx, 28(%esp)     movl    %eax, 4(%esp)     movl    $lc0, (%esp)     call    _printf l2:     cmpl    $10, 28(%esp)     jg  l3     cmpl    $4, 24(%esp)     jne l4 l3:     movl    $0, %eax     leave     .cfi_restore 5     .cfi_def_cfa 4, 4     ret     .cfi_endproc lfe7:     .ident  "gcc: (gnu) 4.8.2"     .def    _printf;    .scl    2;  .type   32; .endef 

then i've compiled command:

gcc -std=c99 -pedantic test.c -o3 -s -o test.asm 

this output:

    .file   "test.c"     .def    ___main;    .scl    2;  .type   32; .endef     .section .rdata,"dr" lc0:     .ascii "%d\12\0"     .section    .text.startup,"x"     .p2align 4,,15     .globl  _main     .def    _main;  .scl    2;  .type   32; .endef _main: lfb7:     .cfi_startproc     pushl   %ebp     .cfi_def_cfa_offset 8     .cfi_offset 5, -8     movl    %esp, %ebp     .cfi_def_cfa_register 5     pushl   %ebx     andl    $-16, %esp     subl    $16, %esp     .cfi_offset 3, -12     call    ___main     movl    8(%ebp), %eax     leal    (%eax,%eax), %edx     movl    $1, %eax     cmpl    $4, %edx     jne l8     jmp l6     .p2align 4,,7 l12:     movl    %ebx, %eax l8:     leal    1(%eax), %ebx     movl    %eax, 4(%esp)     movl    $lc0, (%esp)     call    _printf     cmpl    $11, %ebx     jne l12 l6:     xorl    %eax, %eax     movl    -4(%ebp), %ebx     leave     .cfi_restore 5     .cfi_restore 3     .cfi_def_cfa 4, 4     ret     .cfi_endproc lfe7:     .ident  "gcc: (gnu) 4.8.2"     .def    _printf;    .scl    2;  .type   32; .endef 

so basically, optimization turned on original code transformed this:

#include <stdio.h> int main(int argc, char **argv) {     int dummy = 2 * argc;     int = 1;     if (dummy != 4)         while (i<=10)             printf("%d\n", i++);     return 0; } 

so, can see, there indeed hoisting in c.


Comments

Popular posts from this blog

java - WrongTypeOfReturnValue exception thrown when unit testing using mockito -

php - Magento - Deleted Base url key -

android - How to disable Button if EditText is empty ? -