【问题标题】:Const-qualification of parameters in function declaration函数声明中参数的 const 限定
【发布时间】:2018-12-23 12:26:53
【问题描述】:

我在头文件中有以下函数声明:

extern void flash(const char *message, const enum msg_type type);

基本上,它接受两个参数并将相应的消息推送到全局消息队列中。因为它不需要修改参数,所以我对它们进行了 const 限定。但是,CLion 的静态代码分析器发出了警告:

Clang-Tidy:参数 'type' 在函数声明中是 const 限定的;参数的 const 限定仅对函数定义有影响

这是我的问题:

  1. 我对两个参数都进行了 const 限定,为什么只有后者触发警告?
  2. 真的很糟糕吗?我知道它没有效果,但技术上指定 const 限定符也没有效果。
  3. 我可以去掉这个警告吗?

【问题讨论】:

  • 您没有对第一个参数进行 const 限定。您在指针类型后面添加了const
  • @M.M 你是对的。实际上,我正在限定第一个参数指向的内容。

标签: c constants declaration clion clang-tidy


【解决方案1】:

我对两个参数都进行了 const 限定,为什么只有后者触发警告?

正如您的警告所说,它不会影响原型。它只影响实现。

真的很糟糕吗?

它是噪音,意思是它不会影响任何东西,但除此之外,没有。

我可以去掉这个警告吗?

您可以安全地删除 const 限定符,因为它不是必需的。

但是,使用clang-tidy 抑制一般警告似乎有点混乱。此链接可能会有所帮助:

clang-tidy: How to suppress warnings?

但这些警告实际上可能是一种祝福。不小心写int foo(const char *) 而不是int foo(char * const) 的情况并不少见。后者不会触发此警告,因此如果您收到此警告,则表明您混淆了某些内容。

【讨论】:

    【解决方案2】:

    第一个参数是const char * 类型,或指向常量字符的指针。这意味着您可以向函数传递一个指向您无法修改的字符串的指针,例如:

    const char* msg = "Hello, world!";
    flash(msg, SOME_MESSAGE_TYPE);
    

    msg 中的字符不能更改;它是指向const char 的指针。将其传递给参数类型为char* 的函数将表明该函数可能会更改它们,这是非法的。参数类型中的这个const与调用者相关,所以保留。

    另一方面,enum msg_type 只是一个enum,将被复制到函数中。调用函数时,我不在乎type 的函数体中发生了什么;它不会影响函数之外的任何内容。说 thisconst 并没有什么不同,因此会发出警告。

    如果您将第一个参数更改为const char *const message,那么它也会发出警告。这将表明您无法更改指针 message 指向的内容,调用者也不关心它,因为它传递的任何指针都不会改变。


    这还不错;它告诉你你可能会感到困惑,但在这种情况下它不会伤害任何东西。不过,您仍然应该摆脱警告,因为警告表明存在潜在问题,而用非问题噪音堵塞它们只会降低您阅读重要内容的可能性。


    更改头文件,但不是在实现flash 的地方,第二个参数上没有const。在实现它的地方,保留const,这样你就不会在函数体内实际更改type,但在声明中不需要它。

    【讨论】:

    • +1 不知道函数定义(指定内部实现)和声明(指定外部接口)之间的细微差别
    • @chux 我知道我应该仔细检查一下。我主要使用 C++ 并且知道在细节上存在差异,但是当我这么说时我认为我坚持使用安全的东西(至少在 C11 之前)。因为这是关于类型系统而不是 UB,所以我修改了示例以不直接使用字符串文字。
    • 声明中的常量值不会影响函数的签名,因此不应将您放入函数声明中。为获得最佳实践,该值应通过引用传递。
    • @Arun 问题被标记为 C,而不是 C++; C 没有引用。即使这样做了,msg 已经是一个指针,并且通过值传递 enum 可能会更好。
    • 对我来说似乎很奇怪,我们应该使声明与实现不匹配,但 C/C++ 中有很多奇怪的东西,所以我想我只是称之为“惯用风格”并滚动它。
    猜你喜欢
    • 2019-01-15
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    相关资源
    最近更新 更多