рдХрд╛рдВрд╕реНрдЯ рд╕реА / рд╕реА ++ рдХреЛрдб рдХреЛ рдЧрддрд┐ рдХреНрдпреЛрдВ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ?


рдХреБрдЫ рдорд╣реАрдиреЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рдПрдХ рдкреЛрд╕реНрдЯ рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдПрдХ рдорд┐рдердХ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рдХрд╛рд╕реНрдЯ рд╕реА рдФрд░ рд╕реА ++ рдореЗрдВ рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрдиреБрдХреВрд▓рди рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ ред рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдЗрд╕ рдХрдерди рдХреЛ рд╕рдордЭрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЦрд╛рд╕рдХрд░ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЦреБрдж рдЗрд╕ рдорд┐рдердХ рдкрд░ рдкрд╣рд▓реЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдХрд░рддрд╛ рдерд╛ред рдореИрдВ рд╕рд┐рджреНрдзрд╛рдВрдд рдФрд░ рдХреГрддреНрд░рд┐рдо рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░реВрдБрдЧрд╛, рдФрд░ рдлрд┐рд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рдмреЗрд╕ - SQLite рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдкреНрд░рдпреЛрдЧреЛрдВ рдФрд░ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкрд░ рдЖрдЧреЗ рдмрдврд╝реВрдБрдЧрд╛ред

рд╕рд░рд▓ рдкрд░реАрдХреНрд╖рдг


рдЪрд▓реЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рдерд╛, рд╕реА рдХреЛрдб рдХреЛ рдЧрддрд┐ рдХреЗ рд╕рд╛рде рдмрдврд╝рд╛рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдФрд░ рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рдЙрджрд╛рд╣рд░рдгред рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛рдПрдБ рд╣реИрдВ:

 void func(int *x); void constFunc(const int *x); 

рдФрд░ рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдХреЛрдб рдХреЗ рджреЛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ:

 void byArg(int *x) { printf("%d\n", *x); func(x); printf("%d\n", *x); } void constByArg(const int *x) { printf("%d\n", *x); constFunc(x); printf("%d\n", *x); } 

printf() рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдореЗрдореЛрд░реА рд╕реЗ *x рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЬрд╛рд╣рд┐рд░ рд╣реИ, constByArg() рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдереЛрдбрд╝рд╛ рддреЗрдЬ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ *x рдПрдХ рд╕реНрдерд┐рд░рд╛рдВрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП constFunc() рдмрд╛рдж рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣реИ рди? рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ GCC рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдорд┐рдд рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛрдб рдХреЛ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 $ gcc -S -Wall -O3 test.c $ view test.s 

рдФрд░ рдпрд╣рд╛рдБ byArg() рд▓рд┐рдП рдкреВрд░рд╛ рдХреЛрдбрд╛рдВрддрд░рдХ рдкрд░рд┐рдгрд╛рдо рд╣реИ:

 byArg: .LFB23: .cfi_startproc pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 movl (%rdi), %edx movq %rdi, %rbx leaq .LC0(%rip), %rsi movl $1, %edi xorl %eax, %eax call __printf_chk@PLT movq %rbx, %rdi call func@PLT # The only instruction that's different in constFoo movl (%rbx), %edx leaq .LC0(%rip), %rsi xorl %eax, %eax movl $1, %edi popq %rbx .cfi_def_cfa_offset 8 jmp __printf_chk@PLT .cfi_endproc 

byArg() рдФрд░ constByArg() рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛрдб рдХреЗ рдмреАрдЪ рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ constByArg() рдкрд╛рд╕ call constFunc@PLT , рдЬреИрд╕рд╛ рдХрд┐ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рд╣реИред const рдЦреБрдж рд╣реА рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред

рдареАрдХ рд╣реИ, рд╡рд╣ рдЬреАрд╕реАрд╕реА рдерд╛ред рд╢рд╛рдпрдж рд╣рдореЗрдВ рдПрдХ рдЪрд╛рд▓рд╛рдХ рд╕рдВрдХрд▓рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХрд╣реЛ рдХреНрд▓реЗрдВрдЧред

 $ clang -S -Wall -O3 -emit-llvm test.c $ view test.ll 

рдпрд╣рд╛рдБ рдордзреНрдпрд╡рд░реНрддреА рдХреЛрдб рд╣реИред рдпрд╣ рдХреЛрдбрд╛рдВрддрд░рдХ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рд╣реИ, рдФрд░ рдореИрдВ рджреЛрдиреЛрдВ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛, рддрд╛рдХрд┐ рдЖрдк рд╕рдордЭ рд╕рдХреЗрдВ рдХрд┐ рдореБрдЭреЗ "рдЕрдВрддрд░ рд╕реЗ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдХреЙрд▓ рдХреЛ рдЫреЛрдбрд╝рдХрд░:"

 ; Function Attrs: nounwind uwtable define dso_local void @byArg(i32*) local_unnamed_addr #0 { %2 = load i32, i32* %0, align 4, !tbaa !2 %3 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %2) tail call void @func(i32* %0) #4 %4 = load i32, i32* %0, align 4, !tbaa !2 %5 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %4) ret void } ; Function Attrs: nounwind uwtable define dso_local void @constByArg(i32*) local_unnamed_addr #0 { %2 = load i32, i32* %0, align 4, !tbaa !2 %3 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %2) tail call void @constFunc(i32* %0) #4 %4 = load i32, i32* %0, align 4, !tbaa !2 %5 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %4) ret void } 

рд╡рд┐рдХрд▓реНрдк (рдкреНрд░рдХрд╛рд░) рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ


рдФрд░ рдпрд╣рд╛рдБ рд╡рд╣ рдХреЛрдб рд╣реИ рдЬрд┐рд╕рдореЗрдВ const рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорд╛рдпрдиреЗ рд░рдЦрддреА рд╣реИ:

 void localVar() { int x = 42; printf("%d\n", x); constFunc(&x); printf("%d\n", x); } void constLocalVar() { const int x = 42; // const on the local variable printf("%d\n", x); constFunc(&x); printf("%d\n", x); } 

localVar() рдХреЗ рд▓рд┐рдП рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛрдб, рдЬрд┐рд╕рдореЗрдВ рджреЛ рдирд┐рд░реНрджреЗрд╢ рд╣реИрдВ рдЬреЛ constLocalVar() рдмрд╛рд╣рд░ рдЕрдиреБрдХреВрд▓рд┐рдд рд╣реИрдВ constLocalVar() :

 localVar: .LFB25: .cfi_startproc subq $24, %rsp .cfi_def_cfa_offset 32 movl $42, %edx movl $1, %edi movq %fs:40, %rax movq %rax, 8(%rsp) xorl %eax, %eax leaq .LC0(%rip), %rsi movl $42, 4(%rsp) call __printf_chk@PLT leaq 4(%rsp), %rdi call constFunc@PLT movl 4(%rsp), %edx # not in constLocalVar() xorl %eax, %eax movl $1, %edi leaq .LC0(%rip), %rsi # not in constLocalVar() call __printf_chk@PLT movq 8(%rsp), %rax xorq %fs:40, %rax jne .L9 addq $24, %rsp .cfi_remember_state .cfi_def_cfa_offset 8 ret .L9: .cfi_restore_state call __stack_chk_fail@PLT .cfi_endproc 

LLVM рдорд┐рдбрд▓рд╡реЗрдпрд░ рдереЛрдбрд╝рд╛ рдХреНрд▓реАрдирд░ рд╣реИред constLocalVar() рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реА рдХреЙрд▓ рд╕реЗ рдкрд╣рд▓реЗ load printf() constLocalVar() рдмрд╛рд╣рд░ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ constLocalVar() :

 ; Function Attrs: nounwind uwtable define dso_local void @localVar() local_unnamed_addr #0 { %1 = alloca i32, align 4 %2 = bitcast i32* %1 to i8* call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %2) #4 store i32 42, i32* %1, align 4, !tbaa !2 %3 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 42) call void @constFunc(i32* nonnull %1) #4 %4 = load i32, i32* %1, align 4, !tbaa !2 %5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %4) call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %2) #4 ret void } 

рддреЛ, constLocalVar() рдиреЗ рд░рд┐рдмреВрдЯ *x рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░ рджрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдХреБрдЫ рдЕрдЬреАрдм рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ: рдирд┐рдХрд╛рдпреЛрдВ рдореЗрдВ localVar() рдФрд░ constLocalVar() рдПрдХ рд╣реА рдХреЙрд▓ constFunc() ред рдпрджрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ constFunc() рдиреЗ constFunc() *x рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдпрд╣ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╕рдордЭ рд╕рдХрддрд╛ рдХрд┐ рдЙрд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдиреЗ localVar() рдореЗрдВ *x рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ?

рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдпрд╣ рд╣реИ рдХрд┐ C рдореЗрдВ рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣реИред рд╕реА рдореЗрдВ, const рдХреЗ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рджреЛ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрд░реНрде рд╣реИрдВ:

  • рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдЪрд░ рдХреБрдЫ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рдХрд╛ рдЫрджреНрдо рдирд╛рдо рд╣реИ, рдЬреЛ рд╕реНрдерд┐рд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
  • рдпрд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЪрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд╕реНрдерд┐рд░ рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд╕реЗ рд╕реНрдерд┐рд░ рдорд╛рди рддрдХ рдХрд╛рдВрд╕реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдорд┐рд▓реЗрдЧрд╛ред рджреВрд╕рд░реА рдУрд░, рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА рдпрджрд┐ const рдПрдХ рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рд╣реИ рдЬреЛ рдПрдХ рд╕реНрдерд┐рд░ рдирд╣реАрдВ рд╣реИред

рдпрд╣рд╛рдБ constFunc() рдХрд╛ рдПрдХ рд╡реНрдпрд╛рдЦреНрдпрд╛рддреНрдордХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ:

 // x is just a read-only pointer to something that may or may not be a constant void constFunc(const int *x) { // local_var is a true constant const int local_var = 42; // Definitely undefined behaviour by C rules doubleIt((int*)&local_var); // Who knows if this is UB? doubleIt((int*)x); } void doubleIt(int *x) { *x *= 2; } 

localVar() рдиреЗ localVar() рдХреЛ constFunc() рдкреЙрдЗрдВрдЯрд░ рдХреЛ constFunc() рд╡реИрд░рд┐рдПрдмрд▓ рджрд┐рдпрд╛ред рдЪреВрдВрдХрд┐ рдЪрд░ рд╢реБрд░реБрдЖрдд рдореЗрдВ constFunc() рдирд╣реАрдВ рдерд╛, constFunc() рдПрдХ рдЭреВрдард╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ UB рдХреЛ рдЖрд░рдВрдн рдХрд┐рдП рдмрд┐рдирд╛ рдЪрд░ рдХреЛ рдмрд▓рдкреВрд░реНрд╡рдХ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╕рдВрдХрд▓рдХ рдпрд╣ рдирд╣реАрдВ рдорд╛рди рд╕рдХрддрд╛ рд╣реИ рдХрд┐ constFunc() рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж constFunc() рдЪрд░ рдХрд╛ рдПрдХ рд╣реА рдореВрд▓реНрдп рд╣реЛрдЧрд╛ред constLocalVar() рдореЗрдВ рд╡реИрд░рд┐рдПрдмрд▓ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ const , рдЗрд╕рд▓рд┐рдП рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ рдорд╛рди рдирд╣реАрдВ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдмрджрд▓рд╛ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдмрд╛рд░ рдпрд╣ constFunc() рд▓рд┐рдП UB рд╣реЛрдЧрд╛ , рддрд╛рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ constFunc() рдХреЛ рдЕрдирдмрд╛рдЗрдВрдб рдХрд░ рд╕рдХреЗ рдФрд░ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рд▓рд┐рдЦ рд╕рдХреЗред

рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рд╕реЗ byArg() рдФрд░ constByArg() рдлрд╝рдВрдХреНрд╢рди рдирд┐рд░рд╛рд╢рд╛рдЬрдирдХ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ constByArg() рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ *x const ред

рд▓реЗрдХрд┐рди рдЕрд╕рдВрдЧрддрд┐ рдХрд╣рд╛рдВ рд╕реЗ рдЖрдИ? рдпрджрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ рдорд╛рди рд╕рдХрддрд╛ рд╣реИ рдХрд┐ constFunc() рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ constLocalVar() рдЕрдкрдирд╛ рддрд░реНрдХ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ, рддреЛ рдпрд╣ constFunc() рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдЕрдиреБрдХреВрд▓рди рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд╣реИ рдирд╛? рдирд╣реАрдВред рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ рдирд╣реАрдВ рдорд╛рди рд╕рдХрддрд╛ рд╣реИ рдХрд┐ constLocalVar() рдХрднреА рднреА рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рдЕрдЧрд░ рдпрд╣ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдпрд╛ рдореИрдХреНрд░реЛ рдСрдкрд░реЗрд╢рди рдХрд╛ рд╕рд┐рд░реНрдл рдХреБрдЫ рдЕрддрд┐рд░рд┐рдХреНрдд рдкрд░рд┐рдгрд╛рдо рд╣реИ) рдирд╣реАрдВ рд╣реИ, рддреЛ constFunc() рдЪреБрдкрдЪрд╛рдк рдпреВрдмреА рдЖрд░рдВрдн рдХрд┐рдП рдмрд┐рдирд╛ рдбреЗрдЯрд╛ рдХреЛ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред

рдЖрдкрдХреЛ рдХрдИ рдмрд╛рд░ рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдФрд░ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдмреЗрддреБрдХрд╛ рд▓рдЧрддрд╛ рд╣реИ - рдпрд╣ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, const рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рд▓рд┐рдЦрдирд╛ UB рдХрд╛ рд╕рдмрд╕реЗ рдЦрд░рд╛рдм рдкреНрд░рдХрд╛рд░ рд╣реИ: рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░, рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдпрд╣ рднреА рдкрддрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдпреВрдмреА рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдЬрдм рдХрдВрдкрд╛рдЗрд▓рд░ const рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рдЗрд╕ рддрдереНрдп рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреЛрдИ рдЗрд╕реЗ рдХрд╣реАрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд┐рдП const рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдпрд╣ рд╕рдЪ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реА рдХреЛрдб рдореЗрдВ "рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ" рдХреА рд╢реИрд▓реА рдореЗрдВ const рдЕрд╕реНрд╡реАрдХреГрддрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИред

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдРрд╕реА рдХрдИ рд╕реНрдерд┐рддрд┐рдпрд╛рдБ рд╣реЛрддреА рд╣реИрдВ рдЬрд╣рд╛рдБ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд▓рд┐рдП const рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреВрд╕рд░реЗ рд╕реНрдХреЛрдк рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдпрд╛ рдвреЗрд░ рдкрд░ рдбреЗрдЯрд╛ рд░рдЦрдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рдпрд╛ рдЗрд╕рд╕реЗ рднреА рдмрджрддрд░, рдЖрдорддреМрд░ рдкрд░ рдЙрди рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдЬрд╣рд╛рдВ рдХрдВрдкрд╛рдЗрд▓рд░ const рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЛрдИ рднреА рд╕реНрд╡рд╛рднрд┐рдорд╛рдиреА рд╕рдВрдХрд▓рдХ рдмрд┐рдирд╛ рд╕рдордЭреЗ рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдХреЛрдб рдореЗрдВ x рдПрдХ рд╕реНрдерд┐рд░рд╛рдВрдХ рд╣реИ:

 int x = 42, y = 0; printf("%d %d\n", x, y); y += x; printf("%d %d\n", x, y); 

рдЗрд╕рд▓рд┐рдП const рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд▓рд┐рдП рд▓рдЧрднрдЧ рдмреЗрдХрд╛рд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐:

  1. рдХреБрдЫ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде, рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЗрд╕реЗ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреБрдЫ рдХреЛрдб рдХрд╛рдиреВрдиреА рд░реВрдк рд╕реЗ рдЕрдпреЛрдЧреНрдп рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
  2. рдЙрдкрд░реЛрдХреНрдд рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдкрд╡рд╛рджреЛрдВ рдореЗрдВ, рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрднреА рднреА рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЪрд░ рдПрдХ рд╕реНрдерд┐рд░ рд╣реИред

рд╕реА ++


рдпрджрд┐ рдЖрдк C ++ рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдлрдВрдХреНрд╢рди рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЛрдб рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╣реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ const рдФрд░ рдиреЙрди- const рдУрд╡рд░рд▓реЛрдб рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдиреЙрди- const рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рджреНрд╡рд╛рд░рд╛, рд╕рдВрдХрд▓рдХ рдирд╣реАрдВ), рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрдо рдХреЙрдкреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

 void foo(int *p) { // Needs to do more copying of data } void foo(const int *p) { // Doesn't need defensive copies } int main() { const int x = 42; // const-ness affects which overload gets called foo(&x); return 0; } 

рдПрдХ рдУрд░, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдпрд╣ рдЕрдХреНрд╕рд░ C ++ рдХреЛрдб рдореЗрдВ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рджреВрд╕рд░реА рдУрд░, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЕрдВрддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдпрд╣ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╡реЗ рд╕рдВрдХрд▓рдХ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рднрд╛рд╖рд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИрдВред

SQLite3 рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ


рдкрд░реНрдпрд╛рдкреНрдд рд╕рд┐рджреНрдзрд╛рдВрдд рдФрд░ рджреВрд░рдЧрд╛рдореА рдЙрджрд╛рд╣рд░рдгред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдбрдмреЗрд╕ рдкрд░ const рдХреНрдпрд╛ рдкреНрд░рднрд╛рд╡ рдкрдбрд╝рддрд╛ рд╣реИ? рдореИрдВрдиреЗ SQLite DB (рд╕рдВрд╕реНрдХрд░рдг 3.30.0) рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐:

  • рдпрд╣ const. рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ const.
  • рдпрд╣ рдПрдХ nontrivial code base (200 KLOC рд╕реЗ рдЕрдзрд┐рдХ) рд╣реИред
  • рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдЗрд╕рдореЗрдВ рдХрдИ рддрдВрддреНрд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдорд╛рдиреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВред
  • рдЗрд╕реЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рд╕реАрдорд┐рдд рд▓реЛрдб рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рд▓реЗрдЦрдХ рдФрд░ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддреЗ рд╣реБрдП рдкрд╣рд▓реЗ рд╣реА рд╡рд░реНрд╖реЛрдВ рдмрд┐рддрд╛ рдЪреБрдХреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдпрд╣ рдорд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдХреБрдЫ рднреА рдпрд╛рдж рдирд╣реАрдВ рдХрд┐рдпрд╛ред

рдЯреНрд░реЗрдирд┐рдВрдЧ


рдореИрдВрдиреЗ рд╕реЛрд░реНрд╕ рдХреЛрдб рдХреА рджреЛ рдкреНрд░рддрд┐рдпрд╛рдВ рдмрдирд╛рдИрдВред рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдореЛрдб рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдПрдХ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдХрдорд╛рдВрдб рдореЗрдВ const рдХреЛ рдЪрд╛рд▓реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреВрд░реНрд╡-рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 #define const 

(GNU) sed рдкреНрд░рддреНрдпреЗрдХ рдлрд╛рдЗрд▓ рдХреЗ рдКрдкрд░ рдХрдорд╛рдВрдб sed -i '1i#define const' *.c *.h рд╕рд╛рде рдЬреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реИред

рдмрд┐рд▓реНрдб рдХреЗ рджреМрд░рд╛рди рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП SQLite рдЪреАрдЬреЛрдВ рдХреЛ рдереЛрдбрд╝рд╛ рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдХрдВрдкрд╛рдЗрд▓рд░ const рдФрд░ const рдХреЗ рд╕рд╛рде рдХреЛрдб рдорд┐рдХреНрд╕ рдХрд░рддреЗ рд╕рдордп рдмрд╣реБрдд рд╢реЛрд░ const , рдЗрд╕рд▓рд┐рдП рдЖрдк рддреБрд░рдВрдд рдореЗрд░реЗ рдПрдВрдЯреА- const рдХреЛрдб рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдиреЛрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рдВрдХрд▓рд┐рдд рдХреЛрдб рдХреА рдкреНрд░рддреНрдпрдХреНрд╖ рддреБрд▓рдирд╛ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдЫреЛрдЯрд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╕рдВрдкреВрд░реНрдг рдореЗрдореЛрд░реА рдпреЛрдЬрдирд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдкреВрд░реЗ рдХреЛрдб рдореЗрдВ рд╕рдВрдХреЗрдд рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдореЗрдВ рдмрджрд▓рд╛рд╡ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдХреЗ рдЖрдХрд╛рд░ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрджреЗрд╢ рдХреЗ mnemonic рдирд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ objdump -d libSQLite3.so.0.8.6 рдХрд╛рд╕реНрдЯ ( objdump -d libSQLite3.so.0.8.6 ) рд▓рд┐рдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдлрд╝рдВрдХреНрд╢рди:

 000000000005d570 <SQLite3_blob_read>: 5d570: 4c 8d 05 59 a2 ff ff lea -0x5da7(%rip),%r8 # 577d0 <SQLite3BtreePayloadChecked> 5d577: e9 04 fe ff ff jmpq 5d380 <blobReadWrite> 5d57c: 0f 1f 40 00 nopl 0x0(%rax) 

рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ:

 SQLite3_blob_read 7lea 5jmpq 4nopl 

рд╕рдВрдХрд▓рди рдХрд░рддреЗ рд╕рдордп, рдореИрдВрдиреЗ SQLite рдЕрд╕реЗрдВрдмрд▓реА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдирд╣реАрдВ рдмрджрд▓рд╛ред

рд╕рдВрдХрд▓рд┐рдд рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдг


LibSQLite3.so рдХреЗ рд▓рд┐рдП, рдХрд╛рдВрд╕реНрдЯреЗрдмрд▓ рдХреЗ рд╕рд╛рде рд╕рдВрд╕реНрдХрд░рдг 4,740,704 рдмрд╛рдЗрдЯреНрд╕ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, 4,736,712 рдмрд╛рдЗрдЯреНрд╕ рд╡рд╛рд▓реЗ рдХрд╛рдВрд╕реНрдЯреЗрдмрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд▓рдЧрднрдЧ 0.1% рдЕрдзрд┐рдХ рд╣реИред рджреЛрдиреЛрдВ рд╣реА рдорд╛рдорд▓реЛрдВ рдореЗрдВ, 1374 рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (PLT рдореЗрдВ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЧрд┐рдирддреА рдирд╣реАрдВ), рдФрд░ 13 рдХрд╛рд╕реНрдЯ рдореЗрдВ рдХреЛрдИ рдЕрдВрддрд░ рдерд╛ред

рдХреБрдЫ рдмрджрд▓рд╛рд╡ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд╣реИрдХ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдереЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ рдмрджрд▓реЗ рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ (рдореИрдВрдиреЗ SQLite рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреБрдЫ рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рд╣реИ):

 #define LARGEST_INT64 (0xffffffff|(((int64_t)0x7fffffff)<<32)) #define SMALLEST_INT64 (((int64_t)-1) - LARGEST_INT64) static int64_t doubleToInt64(double r){ /* ** Many compilers we encounter do not define constants for the ** minimum and maximum 64-bit integers, or they define them ** inconsistently. And many do not understand the "LL" notation. ** So we define our own static constants here using nothing ** larger than a 32-bit integer constant. */ static const int64_t maxInt = LARGEST_INT64; static const int64_t minInt = SMALLEST_INT64; if( r<=(double)minInt ){ return minInt; }else if( r>=(double)maxInt ){ return maxInt; }else{ return (int64_t)r; } } 

рдпрджрд┐ рд╣рдо const рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдпреЗ рд╕реНрдерд┐рд░рд╛рдВрдХ static рдЪрд░ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВред рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рдХрд┐ рдЬреЛ рдХреЛрдИ рднреА const рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЙрд╕реЗ рдЗрди рдЪрд░реЛрдВ рдХреЛ static const ред рдпрджрд┐ рд╣рдо static рдФрд░ const рджреЛрдиреЛрдВ рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдЬреАрд╕реАрд╕реА рдлрд┐рд░ рд╕реЗ рдЙрдиреНрд╣реЗрдВ рд╕реНрдерд┐рд░рд╛рдВрдХ рдорд╛рди рд▓реЗрдЧрд╛, рдФрд░ рд╣рдореЗрдВ рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓реЗрдЧрд╛ред рдЗрд╕ рддрд░рд╣ рдХреЗ static const рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЗ рдХрд╛рд░рдг, рддреЗрд░рд╣ рдореЗрдВ рд╕реЗ рддреАрди рдлрдВрдХреНрд╢рдиреНрд╕ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдЭреВрдард╛ рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдареАрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ред

SQLite рдХрдИ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡рд╛рд╕реНрддрд╡рд┐рдХ const рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдЗрд╕рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реЗ рд╣реЛрддреЗ рд╣реИрдВ: рдЬреИрд╕реЗ рдХрд┐ рдПрдХ рдЪрд░ рдХреЗ рд╕рд╛рде рдПрдХ рддреБрд▓рдирд╛ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рд╕реНрдерд┐рд░ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░рдирд╛, рдпрд╛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рдХрджрдо рд╕реЗ рд▓реВрдк рдХреЛ рд░реЛрд▓ рдХрд░рдирд╛ (рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХрд┐рд╕ рддрд░рд╣ рдХреЗ рдЕрдиреБрдХреВрд▓рди рдХрд┐рдП рдЧрдП рдереЗ, рдореБрдЭреЗ рд░рд╛рдбрд╛рд░ рдкрд╕рдВрдж рдерд╛ )ред рдХреБрдЫ рдмрджрд▓рд╛рд╡ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИрдВред SQLite3ParseUri() рдореЗрдВ 487 рдирд┐рд░реНрджреЗрд╢ рд╣реИрдВ, рд▓реЗрдХрд┐рди const рдиреЗ рдХреЗрд╡рд▓ рдПрдХ рдмрджрд▓рд╛рд╡ рдХрд┐рдпрд╛: рдЗрди рджреЛ рддреБрд▓рдирд╛рдУрдВ рдХреЛ рд▓рд┐рдпрд╛:

 test %al, %al je <SQLite3ParseUri+0x717> cmp $0x23, %al je <SQLite3ParseUri+0x717> 

рдФрд░ рдЕрджрд▓рд╛ рдмрджрд▓реА:

 cmp $0x23, %al je <SQLite3ParseUri+0x717> test %al, %al je <SQLite3ParseUri+0x717> 

рдорд╛рдирдХ


рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП SQLite рдПрдХ рдкреНрд░рддрд┐рдЧрдорди рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИ, рдФрд░ рдореИрдВрдиреЗ рдЗрд╕реЗ рдорд╛рдирдХ SQLite рдмрд┐рд▓реНрдб рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд╕реИрдХрдбрд╝реЛрдВ рдмрд╛рд░ рдЪрд▓рд╛рдпрд╛ред рд╕реЗрдХрдВрдб рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рд╕рдордп:

рд╕реНрдерд┐рд░рд╛рдВрдХ
рдмрд┐рдирд╛ рдХрд╛рдВрд╕реНрдЯреЗрдмрд▓
рдХрдо рд╕реЗ рдХрдо
10.658
10.803
рдордВрдЭрд▓рд╛
11.571
11.519
рдЕрдзрд┐рдХрддрдоред
11.832
11.658
рдФрд╕рдд
11.531
11.492

рдирд┐рдЬреА рддреМрд░ рдкрд░, рдореБрдЭреЗ рдмрд╣реБрдд рдЕрдВрддрд░ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ред рдореИрдВрдиреЗ рдкреВрд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реЗ const рд╣рдЯрд╛ рджрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдЕрдВрддрд░ рдерд╛, рддреЛ рдиреЛрдЯрд┐рд╕ рдХрд░рдирд╛ рдЖрд╕рд╛рди рдерд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрджрд┐ рдкреНрд░рджрд░реНрд╢рди рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдВрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рддреЛ рдЫреЛрдЯреЗ рддреНрд╡рд░рдг рднреА рдЖрдкрдХреЛ рдЦреБрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪрд▓реЛ рдПрдХ рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВред

рдореИрдВ рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рди-рд╡реНрд╣рд┐рдЯрдиреА рдпреВ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВред рдпрд╣ рдЕрдзрд┐рдХ рдкреНрд░рд╕рд┐рджреНрдз рдЯреА рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рдорд╛рди рд╣реИ, рдЬреЛ рд╕рдореВрд╣реЛрдВ рдореЗрдВ рдЕрдВрддрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдЯрд┐рд▓ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╡рд┐рд╡рд┐рдзрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рд░реЛрдзреА рд╣реИ рдЬреЛ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рд╕рдордп рдХреЛ рдорд╛рдкрддреЗ рд╕рдордп рд╣реЛрддреЗ рд╣реИрдВ (рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╕рдВрджрд░реНрдн рд╕реНрд╡рд┐рдЪ рдХреЗ рдХрд╛рд░рдг, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдореЗрдВ) рд╕реНрдореГрддрд┐ рдЖрджрд┐ рдХреЗ рдкреГрд╖реНрда)ред рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИ:

рд╕реНрдерд┐рд░рд╛рдВрдХрдмрд┐рдирд╛ рдХрд╛рдВрд╕реНрдЯреЗрдмрд▓
рдПрди100100
рдордзреНрдп рд╢реНрд░реЗрдгреА (рдореАрди рд░реИрдВрдХ)121.3879.62
рдорд╛рди- рд╡рд╛рдЗрдЯрдиреА рдпреВ2912
рдЬреЗрдб-5.10
2-рдкрдХреНрд╖реАрдп рдкреА рдорд╛рди<10 -6
рдФрд╕рдд рдЕрдВрддрд░ рдПрдЪрдПрд▓ рд╣реИ
-0.056 рд╕реЗред
95 рдкреНрд░рддрд┐рд╢рдд рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдЕрдВрддрд░рд╛рд▓
-0.077 ... -0.038 рдПрд╕ред

рдЯреЗрд╕реНрдЯ рдпреВ рдиреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдВрддрд░ рдкрд╛рдпрд╛ред рд▓реЗрдХрд┐рди - рдПрдХ рдЖрд╢реНрдЪрд░реНрдп! - рдмрд┐рдирд╛ const рд╕рдВрд╕реНрдХрд░рдг рддреЗрдЬреА рд╕реЗ рдирд┐рдХрд▓рд╛, рд▓рдЧрднрдЧ 60 рдПрдордПрд╕, рдпрд╛рдиреА 0.5%ред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рдП рдЧрдП "рдЕрдиреБрдХреВрд▓рди" рдХреА рдЫреЛрдЯреА рд╕рдВрдЦреНрдпрд╛ рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдХреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рдереАред рдпрд╣ рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ const рдХрд┐рд╕реА рднреА рдкреНрд░рдореБрдЦ рдЕрдиреБрдХреВрд▓рди const рд╕рдХреНрд░рд┐рдп const , рдЬреИрд╕реЗ рдХрд┐ рдСрдЯреЛ-рд╡реЗрдХреНрдЯрд░рдХрд░рдгред рдмреЗрд╢рдХ, рдЖрдкрдХрд╛ рдорд╛рдЗрд▓реЗрдЬ рдХрдВрдкрд╛рдЗрд▓рд░, рдпрд╛ рдЙрд╕рдХреЗ рд╕рдВрд╕реНрдХрд░рдг, рдпрд╛ рдХреЛрдб рдмреЗрд╕, рдпрд╛ рдХреБрдЫ рдФрд░ рдкрд░ рд╡рд┐рднрд┐рдиреНрди рдЭрдВрдбреЗ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╣ рдХрд╣рдирд╛ рдИрдорд╛рдирджрд╛рд░ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рднрд▓реЗ рд╣реА const рдиреЗ рд╕реА рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рд╣реЛ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕ рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджрд┐рдпрд╛ред

рддреЛ рдХрдмреНрдЬ рдХрд┐рд╕ рдЪреАрдЬ рдХреЗ рд▓рд┐рдП рдЬрд░реВрд░реА рд╣реИ?


рдЗрд╕рдХреЗ рд╕рднреА рджреЛрд╖реЛрдВ рдХреЗ рд▓рд┐рдП, C / C ++ рдореЗрдВ const рдЯрд╛рдЗрдк рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдпрджрд┐ рдЖрдк рдЪрд╛рд▓ рд╢рдмреНрджрд╛рд░реНрде рдФрд░ std::unique_pointer рд╕рдВрдпреЛрдЬрди рдореЗрдВ std::unique_pointer рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╕реНрдкрд╖реНрдЯ рд╕реВрдЪрдХ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред 100 рдХреЗрдПрд▓рдУрд╕реА рд╕реЗ рдЕрдзрд┐рдХ рдкреБрд░рд╛рдиреЗ рд╕реА ++ рдХреЛрдбрдмреЗрд╕ рдореЗрдВ рд╕реВрдЪрдХ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдХреА рдЕрдирд┐рд╢реНрдЪрд┐рддрддрд╛ рдПрдХ рдмрд╣реБрдд рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдереА, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╡рд╢ рд╣реВрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдореИрдВ рдкреНрд░рдХрд╛рд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП const рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкрд░реЗ рдЧрдпрд╛ред рдореИрдВрдиреЗ рд╕реБрдирд╛ рд╣реИ рдХрд┐ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рдпрдерд╛рд╕рдВрднрд╡ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ const рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рд╣реА рдорд╛рдирд╛ рдЧрдпрд╛ рдерд╛ред рдореИрдВрдиреЗ рд╕реБрдирд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдкреНрд░рджрд░реНрд╢рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдХреЛрдб рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ const , рднрд▓реЗ рд╣реА рдХреЛрдб рдХрдо рдкрдардиреАрдп рд╣реЛред рдпрд╣ рдЙрд╕ рд╕рдордп рдЙрдЪрд┐рдд рд▓рдЧ рд░рд╣рд╛ рдерд╛, рд▓реЗрдХрд┐рди рддрдм рд╕реЗ рдореИрдВрдиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рд╕рдЪ рдирд╣реАрдВ рдерд╛ред

Source: https://habr.com/ru/post/hi464777/


All Articles