模板功能中的“参数设置,但未使用”警告

时间:2018-03-20 10:20:31

标签: c++

我得到以下warning: parameter 'tupleValue' set but not used [-Wunused-but-set-parameter],但该参数在return语句中显式使用。 它是否真的意味着在调用序列的后面某处忽略返回值,编译器是否足够酷以在此行上优化它? 这是代码:

template<unsigned int ...Vs, class ...Ts>
typename removeLastType<Ts...>::type internalRemoveData(intValues<Vs...>, std::tuple<Ts...> tupleValue)
{
   return std::forward_as_tuple(std::get<Vs>(tupleValue)...);
}

完整来源位于:https://github.com/copperspice/cs_signal/blob/master/src/cs_internal.h#L316

在Windows中编译:

-- The C compiler identification is GNU 5.3.0  
-- The CXX compiler identification is GNU 5.3.0  

2 个答案:

答案 0 :(得分:3)

实际上不是答案,但你的代码中有未定义的行为,正如@RinatVeliakhmedov指出的那样。 internalRemoveData函数的返回值是std::tuple,由悬空引用组成,即对不再存在的对象的引用。

考虑以下简化案例:

struct X {
   X() { std::cout << "def ctor\n"; }
   ~X() { std::cout << "dtor\n"; }
   void f() { std::cout << "f\n"; }
};

template<int ...Is, class ...Ts>
auto f(std::tuple<Ts...> t) {
  return std::forward_as_tuple(std::get<Is>(t)...);
}

int main() {
   auto res = f<0>(std::tuple<X>{});
   std::cout << "---" << std::endl;
   // std::get<0>(res).f(); // would use no-longer existing object 
}

此程序打印出来:

def ctor
dtor
---

f函数完成后,不再存在X的任何对象。

请注意,此问题可能非常危险,因为程序可以按预期运行。我在Wandbox中使用未注释的std::get<0>(res).f();语句尝试了它,程序打印出f并且没有显示任何错误。未定义的行为也包括预期的行为。

答案 1 :(得分:1)

作为原始代码的作者之一,我认为这里的行为定义明确,但原因有点微妙。这是我的逻辑。如果我错过了什么,那就让我们继续讨论。

internalRemoveData方法接收一个值元组,并返回一个具有完全相同数据类型的值元组,减去最后一个元素。分别考虑元组中的每个元素,只有三种可能的情况很重要。

  1. 如果元素是值类型,则forward_as_tuple函数将产生左值引用。此左值引用将分配给返回元组的相应元素,这是一个值类型。这将从输入复制到输出,没有悬空参考。

  2. 如果元素是左值引用,则它必须已经是对某个有效原始对象的引用。它将作为左值引用转发,然后绑定到输出中相应的左值引用。

  3. 如果元素是右值引用,它也必须已经是对某个有效原始对象的引用。我们得到与左值参考案例相同的行为。

  4. 关键是看到返回类型与forward_as_tuple返回的类型相同。

    如果此问题已关闭,请在我们的YouTube频道上查询原始问题:https://www.youtube.com/watch?v=uK-2jzB41c4