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
Post a Comment