这两个表达之间有区别吗?

Is there difference between these two expressions?

由于我的编译器为这两段代码提供了不同的统计信息,我想知道是什么让它们有所不同,如果有的话?

第一个:

typedef const struct process_data
{
   uint8_t *name;
   void (*p_func)(void);
} process_data_t;

process_data_t processes = {15,16};

第二个是:

typedef struct process_data
{
   uint8_t *name;
   void (*p_func)(void);
} process_data_t;

const process_data_t processes = {15,16};

请注意,const 限定符已从类型定义移至结构定义。对我来说,这两个摘录之间没有区别,但是 compiler/linker 统计数据表明,使用第二段代码时,消耗的闪存(该平台是一个资源受限的微控制器)更少。

常量存储在只读内存中——我猜你只是在移动数据所在的位置。在没有看到更多信息的情况下很难说 100%。

声明的数据定义 const 与常规 constness 之间存在差异,因为如果您丢弃 const ,它会变成未定义的行为(至少在 C++ 中)来自使用限定符定义的对象。

在 language-lawyering 之外,理由很明显:我们希望将这些作为 read-only 图像的一部分,同时仍然允许两个知道自己在做什么的人使用 const_cast ,因为也有 good reasons

在 C 中,我们有几乎相同的动机:将常量放入 read-only 内存中,但允许转换工作。当限定符附加到类型时,这并不能强有力地保证用户打算将变量转到 read-only 内存,因此编译器可能会在此处谨慎行事。

编译器在解释这些声明时可以有一定的自由度,但总的来说,区别在于:

  • typedef"says":这是一个永远是const的类型,意思是没有"legal"的方式去掉const-nes of any 这种类型的变量。每当您传递这种类型的数据或指向它的指针时,它们都是常量。当然,强制转换 "works",但仅限于另一种类型,并且可能导致未定义的行为。

  • const数据"says":这个数据是const,但是,这个类型的其他数据可能不是,所以,至少有一些"taking away const-nes" 在这种类型的变量和指针之间是可以的。当然,如果有人将指向此数据的指针转换为 non-const 而它确实在 read-only 内存中,我们就有麻烦了。

所以,底线是一样的,但是有细微的差别。编译器如何解释这实际上取决于编译器。很可能 typedef 非常罕见(根据我的经验),因此编译器针对更常见的情况进行了优化。