我试图找出差异"引擎盖下"在使用try {
InitializationValues iv = new InitializationValues(NSS_JSS_Utils.getFireFoxProfilePath());
iv.installJSSProvider = false;
CryptoManager.initialize(iv);
cm = CryptoManager.getInstance();
} catch (KeyDatabaseException | CertDatabaseException | GeneralSecurityException | NotInitializedException e) {
e.printStackTrace();
} catch (AlreadyInitializedException e) {
cm = CryptoManager.getInstance();
}
CustomPasswordCallback pcb = new CustomPasswordCallback();
cm.setPasswordCallback(pcb);
Enumeration< ? > emModules = cm.getModules();
和constexpr
来定义整数和字符串文字之间。
preprocessor macro
在使用#define FIRST_STRING "first_stringer"
constexpr char second_string[] = "second_stringer";
#define FIRST_INT 1234
constexpr int second_int = 12345;
int main ()
{
printf("%s\n", second_string);
printf("%s\n", FIRST_STRING);
printf("%d\n", FIRST_INT);
printf("%d\n", second_int);
return 0;
}
void hello() {
printf("%s\n", second_string);
printf("%s\n", FIRST_STRING);
printf("%d\n", FIRST_INT);
printf("%d\n", second_int);
}
g++ -S main.cpp -std=c++11
在检查汇编代码时,我们可以在两个函数中观察到指令 .file "main.cpp"
.section .rodata
.LC0:
.string "first_stringer"
.LC1:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $_ZL13second_string, %edi
call puts
movl $.LC0, %edi
call puts
movl $1234, %esi
movl $.LC1, %edi
movl $0, %eax
call printf
movl $12345, %esi
movl $.LC1, %edi
movl $0, %eax
call printf
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.globl _Z5hellov
.type _Z5hellov, @function
_Z5hellov:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $_ZL13second_string, %edi
call puts
movl $.LC0, %edi
call puts
movl $1234, %esi
movl $.LC1, %edi
movl $0, %eax
call printf
movl $12345, %esi
movl $.LC1, %edi
movl $0, %eax
call printf
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size _Z5hellov, .-_Z5hellov
.section .rodata
.align 16
.type _ZL13second_string, @object
.size _ZL13second_string, 16
_ZL13second_string:
.string "second_stringer"
.align 4
.type _ZL10second_int, @object
.size _ZL10second_int, 4
_ZL10second_int:
.long 12345
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits
和movl $1234, %esi
。即即使movl $12345, %esi
存储在单独的部分constexp int
constexpr int
之间也没有明显差异。
另一方面,对于字符串文字,我们看到指令_ZL10second_int
和movl $_ZL13second_string, %edi
将它们各自的字符串文字映射到两个不同的部分。
这两个部分有什么区别?加载可执行文件后,它们是否映射到主内存的不同部分?如果是的话,访问速度比另一部分快一部分吗?我知道我可以描述性能影响,但我想了解这两个部分之间的理论原因和区别。
答案 0 :(得分:3)
这些在功能上是等同的。请注意,两种情况下的实际数据都是使用.string
指令声明的。唯一的区别在于标签名称,其中实际上是C ++对象的那个(second_string
)具有错位名称,而宏只有一个通用标签名称。
如果您在Linux上的可执行文件上运行objdump
,您会注意到这两个字符串都存储在.rodata
部分中:
String dump of section '.rodata':
[ 4] %s^J
[ 8] first_stringer
[ 17] %d^J
[ 20] second_stringer
答案 1 :(得分:2)
原因是宏由预处理器处理,但constexpr由编译器处理。因此,constexpr不仅仅是字符串替换,例如它会检查类型。
所以即使是组装也是一样的,从我的角度来看,constexpr是一个更好的选择