C++ 编译器拒绝放弃对不执行任何操作的函数的调用

C++ 编译器拒绝放弃对不执行任何操作的函数的调用,c++,c++11,C++,C++11,以下代码中的add方法不起任何作用: template <class StateNeighbor> struct NoGraph { using State = typename StateNeighbor::State; void add(const State &s) const {(void)s;} ... }; 正如注释所说,在本例中,编译器不再调用f。那么,为什么编译器拒绝放弃对在原始代码中不做任何事情的函数的调用呢?我使用的是gccver

以下代码中的
add
方法不起任何作用:

template <class StateNeighbor> struct NoGraph {
    using State = typename StateNeighbor::State;
    void add(const State &s) const {(void)s;}
    ...
};
正如注释所说,在本例中,编译器不再调用
f
。那么,为什么编译器拒绝放弃对在原始代码中不做任何事情的函数的调用呢?我使用的是
gcc
version4.8.2,并使用
-Wall-Wextra-Werror-std=c++11-pedantic-O2
进行编译


更新:问题已解决。我基于二进制文件比较的假设是错误的。使用-DNDEBUG编译并按照其中一条注释中的建议对生成的二进制文件运行
strip
后,两个二进制文件匹配。

二进制文件可能由于不重要的原因(例如调试信息)而更改。要可靠地检查调用是否真的被删除,请使用
-S
标志并检查生成的程序集。@user4815162342当我使用优化标志(如-O2或-O3)时,调试信息是否存在?同样,同样的编译器也应该为原型插入这些信息,在这种情况下,二进制文件也会有所不同…@AlwaysLearning:是的。要删除调试信息,您应该使用
-DNDEBUG
进行编译,然后在生成的二进制文件上运行
strip
。但是+1与检查程序集的想法无关。这确实是唯一可以确定的方法。即使我连续两次编译完全相同的文件,我的编译器(clang)也会更改二进制文件…即使您设法删除所有调试信息,也可能会出现某种辅助数据。检查程序集以查找简单的函数调用实际上相当容易,您只需要查找函数的名称,就可以找到被调用或未被调用的实例。
template <class Open, class Heuristic,
          template <class State> class GoalHandler = SingleGoalHandler,
          template <class StateNeighbor> class Graph = NoGraph>
struct Astar {
    using Node = typename Open::Node;
    using CostType = typename Node::CostType;
    using NodeUP = typename Node::NodeUP;
    using State = typename Node::State;
    using StateUP = typename Node::StateUP;
    using Neighbor = typename State::Neighbor;

    Astar(const State &start, const GoalHandler<State> &goalHandler, Graph<Neighbor> &graph)
        : start_(start), goalHandler_(goalHandler), graph_(graph), oc_(),
          cur_(nullptr), children_() {
          graph_.add(start); // When Graph is instantiated to be NoGraph, the
                             // binary should be the same with or without this
                             // line!
    }
    ...
struct A{
    void dump() const {std::cout << "This does something." << std::endl;}
};

struct B1 {
    void f(const A& a) const {(void)a;}
};
struct B2 {
    void f(const A& a) const {a.dump();}
};


template <class T1, class T2>
struct B{
    B(const T1& t1, T2& t2) : t1_(t1), t2_(t2) {
        t2.f(t1); // The binary is the same whether this line is present or not
    }
    void dump() const {
        std::cout << demangle(typeid(T2).name()) << std::endl;
    }
private:
    T1 t1_;
    T2 &t2_;
};

int main() {
    A a;
    B1 b1;
    B<A,B1> b(a, b1);
    b.dump();
    return 0;
}