2011-12-12 42 views
0

我们有一个巨大的二进制文件,并且在命名前定义的常量说那么header1.h:Linux的C++二进制命名空间

namespace One 
{ 
    namespace Two 
    { 

      const String TEST_DATE_TIME = "DDMMYYYY"; // Line number say 32 
      // ................ Around 2500 such constants .......... 
    } 
} 

的问题是,当我们运行与仪器(-finstrument-功能和_cyg二进制*函数),我们看到类似下面的方法在我们的报告 - 不都在数据段声明:

__tcf_2275,header1.h: 32 

它意味着,在执行过程中,编译器花了一些时间来创建命名空间常量 - 但为什么呢?我在样本文件中看不到相同的行为(在名称空间中声明常量)。

此外 -

nm a.out| grep __tcf_ | more 

000000000807acf8 t __tcf_1234 
000000000807ad60 t __tcf_1456 
............................ 
000000000816ddd0 t __tcf_1125 
............................ 

addr2line -Cfe a.out 0x807acf8 0x807ad60 

__tcf_2275 
header1.h:2322 
__tcf_2274 
header1.h:2321 

当然我们可以说,在执行过程中的命名空间常数由编译器构成。我怎样才能减少它们的执行开销和ii)为什么将定义为't'部分?

+0

您应该使用'nm -C a.out'来对C++符号名称进行解映射。 –

回答

2

你肯定会搞乱编译器,以及他在什么时候工作。

如果你定义的东西作为const String TEST = "something";你基本上创建String对象(无论字符串,它是),除非String只是一个定义char *。因此,在程序运行之前,运行这些对象的构造函数(这不是也不能在编译时完成,因此它必须在运行时发生)。

我不知道你是如何使用这些常量,但如果他们与const char*只是后来在使用时,你应该能够提高性能提升不少,只列出那些:

namespace foo { 
    namespace bar { 
     const char *MY_CONSTANT = "hello world!"; 
    } 
} 

但是,如果您试图再次将这些对象用作某种String对象,则可能会在以后创建额外开销。它基本上是“在启动时完成的工作”与“在使用它们时要完成的工作”。常量不会说没有涉及的工作(与常量字面量或常量整型值一样)。

至于问题的第二部分,您必须等待其他人解释这一点,因为我不熟悉它。尽管在运行时动态分配(以及要运行的代码),但您不会在.data部分看到此代码。虽然使用的字符串文字应该在.data之内。

+0

另外值得注意的是,当你在主体之前构造一个对象时,你将冒着抛出的异常终止你的程序,因为没有办法捕捉它。 –