【问题标题】:Why doesn't clang -Wunused-member-function warn about an unused member function?为什么 clang -Wunused-member-function 不对未使用的成员函数发出警告?
【发布时间】:2019-06-14 19:01:29
【问题描述】:

我正在编译一个非常基本的程序,试图从-Wunused-member-function 触发输出。

test.cpp:

#include <iostream>

class A {
    public:
    void foo() { std::cout << "Called foo" << std::endl; }
    void foo_unused() { std::cout << "Unused foo" << std::endl; }
};

int main() {
    A obj;
    obj.foo();
    return 0;
}

以下命令的输出

clang++ -std=c++17 -Wall -Wunused -Wunused-member-function \
        -Wunused-function -Wunneeded-member-function \
        test.cpp -o 测试

不幸的是,甚至没有包含一个警告。我希望编译器会警告foo_unused 未被使用。

我在这里错过了不同的行为吗?不然clang为什么不抱怨没有使用的成员函数呢?

【问题讨论】:

  • 因为它是公开的?尝试将其设为私有
  • 如果您将 void foo_unused() 设为私有 - 它会按预期工作。由于foo_unused 是公共类成员(类型接口),这没有任何问题。编译器/链接器会在进行dead code elimination 优化时简单地删除它。
  • 问题是公共方法可以在任何地方使用。所以没有办法在一个编译单元中检查它。它需要在链接阶段完成,而不是编译阶段。
  • @Adam 根据 C++,当您定义一个类(结构、联合)时 - 您定义的是一个类型,而不是这种类型的对象(如 A obj;)。所以按照C++语言A类是完全正确的,因为A类型没有错。
  • @VictorGubin,不,私人不会改变任何东西:godbolt.org/z/TM8GdYbe8

标签: c++ clang compiler-warnings


【解决方案1】:

您必须将类放在匿名命名空间中才能显示警告:

namespace
{
class A {
    public:
    void foo() { std::cout << "Called foo" << std::endl; }
    void foo_unused() { std::cout << "Unused foo" << std::endl; }
};
}

您现在可以看到警告:https://godbolt.org/z/15Buo-

原因是这个版本也可以激活对公共方法的clang检查,因为你明确表示这个类将无法在另一个翻译单元中访问。

【讨论】:

  • 谢谢,这确实有效。我想知道是否有办法在链接阶段检查一个大项目。
  • 我不认为有这样的东西可用。至少我一无所知:(
  • @Adam Linker 不会在任何情况下将未使用的代码包含到二进制文件中,因为如果您的类不是共享库/DLL 的一部分。如果您启用完整的程序优化,即 LTO,链接器会警告您。
  • 我明白,但我也想从我的代码中删除未使用的函数,因此我想查看我的项目中实际未使用的函数。
  • @VictorGubin 我尝试启用 LTO 并添加所有可能的警告标志,但没有出现警告。
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多