C++ 带有常量对象的代码大小

C++ 带有常量对象的代码大小,c++,arm,embedded,extern,C++,Arm,Embedded,Extern,我有一些源文件,其中需要一些const变量。在提供的框架中,有一个.hpp头文件,其中包含这些变量的定义(不仅仅是声明),这个头文件包含在我前面提到的源文件中。然后我意识到,我的每个源文件都包含RO dataconst变量的一个副本,因此为了减少内存占用(我在Ebedded系统上工作),我又制作了一个.hpp,它包含在我的源文件中,并且包含对这些变量的extern引用(包含在其他地方) 为什么呢 更新: 我犯了错误。具体来说,这里是链接器映射文件的一个片段: (注:RW、ZI已删除) 不使用外部

我有一些源文件,其中需要一些
const
变量。
在提供的框架中,有一个.hpp头文件,其中包含这些变量的定义(不仅仅是声明),这个头文件包含在我前面提到的源文件中。
然后我意识到,我的每个源文件都包含RO data
const
变量的一个副本,因此为了减少内存占用(我在Ebedded系统上工作),我又制作了一个.hpp,它包含在我的源文件中,并且包含对这些变量的
extern
引用(包含在其他地方) 为什么呢

更新: 我犯了错误。具体来说,这里是链接器映射文件的一个片段: (注:RW、ZI已删除)
不使用外部程序:
代码:1192
(包括数据):84
反渗透数据:144

使用外部程序:
代码:1392
(包括数据):216
反渗透数据:144

但我的错误有更多的新问题,而不是答案:

  • 在这种情况下,为什么RO(常量数据)大小没有改变
  • 此范围内的inc.数据是什么

  • 当定义不是
    extern
    时,编译器可以将其内联,因此它们直接存储在代码中的“立即加载”指令中。
    (这称为“恒定折叠”。)

    使它们
    extern
    对编译器隐藏定义,迫使编译器在编译期间存储值,并生成代码以在运行时获取它们

    它们不存储在只读段中,因为它们需要在程序启动时初始化,因此必须是可写的。

    只读段仅适用于永不更改的内容,例如字符串文本的内容。

    当定义不是
    extern
    时,编译器可以内联它们,因此它们直接存储在代码中的“load immediate”指令中。
    (这称为“恒定折叠”。)

    使它们
    extern
    对编译器隐藏定义,迫使编译器在编译期间存储值,并生成代码以在运行时获取它们

    它们不存储在只读段中,因为它们需要在程序启动时初始化,因此必须是可写的。

    一个只读段只对不改变的事物有好处,例如字符串文字的内容。C++的基本类型和没有外部链接的常量,除非一个地址,否则它没有存储或地址。相反,文本值被插入到代码中,就像您键入了它的数值一样。例如,代码:

    const NUM = 25 ;
    int n1 = NUM ;
    int n2 = NUM ;
    
    将生成与以下内容相同的代码:

    int n1 - 25 ;
    int n2 = 25 ;
    
    这是因为插入文字值所需的指令比从只读内存复制该值所需的指令要少

    但是,如果您有代码:

    const NUM = 25 ;
    int* np = &NUM ;
    
    然后
    NUM
    将被强制存储

    当您将const声明为external时,则表示该值存在于其他位置,并且链接器将分配该值。如果在单独的模块中定义,编译器无法知道它将拥有的值,也无法知道其他模块是否会使用它的地址,因此必须显式存储它-这使得只读数据空间和代码空间都更大


    <> P>在函数或类作用域之外C++中的const变量具有隐式静态链接,在C中它们隐含地 ExtNe>/Cuff>。因此,您可能会发现,如果使用C编译,结果会有所不同。对于互操作性,如果在头文件中声明const,则可能明明声明它“代码> static < /COD>”以确保两种语言中的相同语义。

    < P>基本类型的常量和C++中的外部链接都没有存储或地址,除非一个地址。相反,文本值被插入到代码中,就像您键入了它的数值一样。例如,代码:

    const NUM = 25 ;
    int n1 = NUM ;
    int n2 = NUM ;
    
    将生成与以下内容相同的代码:

    int n1 - 25 ;
    int n2 = 25 ;
    
    这是因为插入文字值所需的指令比从只读内存复制该值所需的指令要少

    但是,如果您有代码:

    const NUM = 25 ;
    int* np = &NUM ;
    
    然后
    NUM
    将被强制存储

    当您将const声明为external时,则表示该值存在于其他位置,并且链接器将分配该值。如果在单独的模块中定义,编译器无法知道它将拥有的值,也无法知道其他模块是否会使用它的地址,因此必须显式存储它-这使得只读数据空间和代码空间都更大


    <> P>在函数或类作用域之外C++中的const变量具有隐式静态链接,在C中它们隐含地 ExtNe>/Cuff>。因此,您可能会发现,如果使用C编译,结果会有所不同。对于互操作性,如果您在头文件中声明const,那么为了确保两种语言中的语义相同,显式声明它
    static
    可能是明智的做法。

    Yap,我还认为这会导致代码大小增加。但是RO数据(常量数据)呢?如果一个值是
    const
    ,编译器通常可以轻松地将该值作为代码的一部分内联。如果在使用常量的所有时间都发生这种情况,则它永远不需要自己的内存位置。如果相同的常量被标记为
    extern
    ,则编译器不知道该值,并且在运行时被迫读取该值,并将该值存储在内存中的某个位置。我没有同时包含这两个头。在这两个测试用例中,只有一个:有定义或有外部引用。没有外部,有时甚至不需要实际常量。编译器使用了其他技巧,这些技巧的最终结果与使用常量时的结果相同。@SvenNilsson我不确定这将如何继续