【问题标题】:GCC C warning "duplicate ‘const’ declaration "GCC C 警告“重复‘const’声明”
【发布时间】:2019-05-21 07:34:53
【问题描述】:

我为什么会得到

重复的'const'声明说明符[-Wduplicate-decl-specifier]

为了这个声明?

extern uint8_t CalculateChecksum(const communicationBlock_t const *messageBlock);

communicationBlock_t 是一个结构体。

我不希望该函数能够更改参数指向的结构,也不希望它能够将该参数指向其他地方。

我做错了什么?

【问题讨论】:

  • const 始终适用于其左侧的内容。如果左侧没有任何内容,则(并且仅在那时)它适用于右侧的内容。

标签: c gcc gcc-warning


【解决方案1】:

您编写的两个const 关键字都适用于communicationBlock_t。你可能想要这个:

extern uint8_t CalculateChecksum(const communicationBlock_t * const messageBlock);

规则是:const 适用于左边,除非它是最左边的说明符,否则它适用于右边。

【讨论】:

  • 天啊!如此明显,但我就是看不到:-/
【解决方案2】:

写就够了

uint8_t CalculateChecksum(const communicationBlock_t* messageBlock);

这意味着您无法更改指向的内容。如果你想阻止一个指针被分配到不同的地址,你可以写* const

但这不是必需的,messageBlock 是原始指针的本地副本,调用者不应该关心该函数在内部对它做了什么。

这是风格问题:

有些人认为,通过保持函数内部的 const 限定,以某种方式增加了额外的安全性。他们还认为写void func (const int n) 之类的东西在某种程度上是有意义的。许多宣扬这种风格的是 C++ 程序员,他们习惯于 const 限定成员函数——这完全是另外一回事,无论如何都不能在 C 中完成。

其他人(像我一样)认为带有* const 的 const 限定参数被认为是不必要的混乱,会使读者感到困惑,因为函数声明将被视为函数调用者的文档,而不是函数的实现者函数定义。

【讨论】:

  • 这太棒了,感谢您写下我对 * const*(以及一般的 const 标量)作为参数的感受。你确定最后一点,关于没有从const type * constconst void * 的转换?
  • @unwind 对于 memcpy 的情况,它违反了简单赋值规则(在参数传递期间适用)。从 6.5.16.1 开始:“left 指向的类型具有 right 指向的类型的所有限定符”。对于一般的指针转换,C 标准只说明了允许的内容,6.3.2.3 §2 “对于任何限定符 q,指向非 q 限定类型的指针可以转换为指向 q 限定版本的指针类型”,使其隐含 UB。
  • 好吧......我仍然感到困惑,因为const type * const 中的第二个const 当然与所指向的类型无关。所以应该没关系吧?我试过了,当将const char * const 作为第二个参数传递给memcpy() 时,GCC 确实构建得很好(但当然这并不能证明太多)。
  • @unwind 其实你是对的。标准说“左边指向的类型”。 const type* const 指向的类型是const type。不会发生丢弃限定符的指针转换,它有效的原因与const int x; int y=x; 有效的原因相同。我将删除那部分答案。
  • 谢谢,感觉好多了。 :) 另外,我的第一条评论中有错字,第一个代码格式文本的末尾有一个星号错误但我无法编辑,删除它会使整个评论链变得 b0rken。
猜你喜欢
  • 2015-08-21
  • 1970-01-01
  • 2020-07-28
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
相关资源
最近更新 更多