如何在启用-Wall编译时抑制“逗号运算符左操作数无作用”警告?
启用-Wall编译时抑制未使用值警告的方法及替代语法
问题背景
我们通过折叠表达式创建包含重复元素的数组,代码如下:
#include <array> #include <utility> template <std::size_t N> class A { int m_x; public: static constexpr std::size_t size = N; A(int x) : m_x{x} { } int f() const noexcept { return m_x; } int g() const noexcept { return m_x * m_x; } }; template <typename U, std::size_t... I> auto get_array_impl(const U& m, std::index_sequence<I...>) { return std::array<int, m.size + 1>{ m.g(), (I, m.f())... }; } template <typename U> auto get_array(const U& m) { return get_array_impl(m, std::make_index_sequence<m.size>{}); } int main() { A<3> x{8}; auto a = get_array(x); return 0; }
启用-Wall编译时会触发如下警告:
main.cpp:18:50: warning: left operand of comma operator has no effect [-Wunused-value]
18 | return std::array<int, m.size + 1>{ m.g(), (I, m.f())... };
此处我们仅借助可变参数展开重复调用m.f(),无需使用I的值,但编译器会因I被丢弃发出警告。以下是两种解决思路:
方法一:局部抑制警告
通过编译器警告控制指令,在目标代码段临时禁用-Wunused-value警告,完成后恢复。以GCC/Clang为例:
template <typename U, std::size_t... I> auto get_array_impl(const U& m, std::index_sequence<I...>) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" return std::array<int, m.size + 1>{ m.g(), (I, m.f())... }; #pragma GCC diagnostic pop }
该方法改动小,适合快速解决问题,但依赖编译器特性,跨平台时需注意差异(如MSVC需使用__pragma(warning(suppress:4100)))。
方法二:使用无警告的语法变体
改用不依赖未使用值的写法,从根源避免警告,推荐两种方式:
方式1:显式转换为void类型
将I转换为void,明确告知编译器我们有意丢弃该值:
template <typename U, std::size_t... I> auto get_array_impl(const U& m, std::index_sequence<I...>) { return std::array<int, m.size + 1>{ m.g(), (static_cast<void>(I), m.f())... }; }
方式2:折叠表达式配合空操作
借助C++17折叠表达式,用空操作占位触发重复展开,同时调用m.f():
template <typename U, std::size_t... I> auto get_array_impl(const U& m, std::index_sequence<I...>) { return std::array<int, m.size + 1>{ m.g(), (void(I), m.f())... }; }
这种写法清晰标准,无编译器兼容性问题,是更推荐的方案。
总结
- 若需最小改动代码,优先选择局部抑制警告的方法,但需关注跨平台适配;
- 若追求标准无警告的代码,推荐使用**
static_cast<void>(I)**的写法,明确表达丢弃值的意图,代码可读性与兼容性更佳。
内容的提问来源于stack exchange,提问作者francesco
相关产品推荐
相关产品推荐

