You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

clang-tidy对boost::variant报未初始化误报的排查咨询

Clang-tidy False Positive: Uninitialized 'id' Field When Using boost::variant with Custom Copy Constructor

This looks like a false positive from the Clang Static Analyzer (the engine behind clang-tidy's core.uninitialized.Assign check), not an issue with your code or Boost. Let's break down what's happening:

Your Code Context

First, let's recap your minimal example for clarity:

#include <boost/variant.hpp>
class Size {
public:
    Size() = default;
    Size(const Size &sz) : width(sz.width) {} // Custom copy ctor matching cv::Size's behavior
    int width{0};
};
struct B {
    Size size;
};
struct A {
    Size size;
    uint32_t id{0}; // Explicit in-class initializer for 'id'
};
int main() {
    using T = boost::variant<A, B>;
    T config = B(); // Only constructing a B instance in the variant
}

Why the False Positive Happens

The analyzer's error trace shows it incorrectly thinks the implicit move constructor of A is being called during the variant's initialization—but your code never constructs an A!

The root cause stems from two factors working together:

  1. Boost.Variant's internal implementation: The variant type reserves storage for all possible alternative types (both A and B here). The analyzer's path exploration gets confused by the template-heavy logic in Boost.Variant and mistakenly follows a code path that assumes A is being constructed.
  2. Custom copy constructor for Size: When you replace Size's copy constructor with = default;, the analyzer can easily track initialization flows through trivial types. The custom copy constructor seems to throw off the analyzer's data-flow analysis, leading it to incorrectly conclude A::id is uninitialized (even though it has an explicit in-class initializer).

How to Fix/Work Around It

Since you can't modify cv::Size (the real-world equivalent of your Size class), here are practical solutions:

  • Suppress the warning locally: Add a comment to tell clang-tidy to ignore this specific false positive. For example, mark the A struct definition:

    struct A {
        Size size;
        uint32_t id{0};
    }; // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign)
    

    Or use a file-level suppression if this pattern appears multiple times.

  • Upgrade your Clang/LLVM tools: Your versions are quite old (commits from several years ago). Newer releases of clang-tools-extra have fixed many analyzer false positives related to template-heavy libraries like Boost.

  • Explicitly define A's constructors: Adding an explicit default constructor can help the analyzer recognize the initialization is intentional:

    struct A {
        A() = default;
        Size size;
        uint32_t id{0};
    };
    

Full Error Log (For Reference)

test_variant.cc:15:8: warning: Value assigned to field 'id' in implicit constructor is garbage or undefined [clang-analyzer-core.uninitialized.Assign]
struct A {
^
test_variant.cc:22:5: note: Calling move constructor for 'variant'
T config = B();
^
libraries/boost/include/boost/variant/variant.hpp:1880:9: note: Calling 'variant::internal_apply_visitor'
operand.internal_apply_visitor(visitor);
^
libraries/boost/include/boost/variant/variant.hpp:2466:16: note: Calling 'variant::internal_apply_visitor_impl'
return internal_apply_visitor_impl(
^
libraries/boost/include/boost/variant/variant.hpp:2452:16: note: Calling 'visitation_impl'
return detail::variant::visitation_impl(
^
libraries/boost/include/boost/variant/detail/visitation_impl.hpp:225:5: note: Control jumps to 'case 0:' at line 238
switch (logical_which)
^
libraries/boost/include/boost/variant/detail/visitation_impl.hpp:240:11: note: Calling 'visitation_impl_invoke'
, BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
^
libraries/boost/include/boost/preprocessor/repetition/repeat.hpp:29:26: note: expanded from macro 'BOOST_PP_REPEAT'
# define BOOST_PP_REPEAT BOOST_PP_CAT(BOOST_PP_REPEAT_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
^
libraries/boost/include/boost/preprocessor/cat.hpp:22:32: note: expanded from macro 'BOOST_PP_CAT'
# define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
^
libraries/boost/include/boost/preprocessor/cat.hpp:29:34: note: expanded from macro 'BOOST_PP_CAT_I'
# define BOOST_PP_CAT_I(a, b) a ## b
^
note: (skipping 21 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
libraries/boost/include/boost/preprocessor/repetition/repeat.hpp:53:56: note: expanded from macro 'BOOST_PP_REPEAT_1_2'
# define BOOST_PP_REPEAT_1_2(m, d) BOOST_PP_REPEAT_1_1(m, d) m(2, 1, d)
^
libraries/boost/include/boost/preprocessor/repetition/repeat.hpp:52:36: note: expanded from macro 'BOOST_PP_REPEAT_1_1'
# define BOOST_PP_REPEAT_1_1(m, d) m(2, 0, d)
^
libraries/boost/include/boost/variant/detail/visitation_impl.hpp:231:16: note: expanded from macro 'BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE'
return (visitation_impl_invoke)( \
^
libraries/boost/include/boost/variant/detail/visitation_impl.hpp:154:12: note: Calling 'visitation_impl_invoke_impl'
return (visitation_impl_invoke_impl)(
^
libraries/boost/include/boost/variant/detail/visitation_impl.hpp:112:12: note: Calling 'move_into::internal_visit'
return visitor.internal_visit(
^
libraries/boost/include/boost/variant/variant.hpp:507:23: note: Calling implicit move constructor for 'A'
new(storage_) T(::boost::detail::variant::move(operand));
^
test_variant.cc:15:8: note: Value assigned to field 'id' in implicit constructor is garbage or undefined
struct A {

内容的提问来源于stack exchange,提问作者user823255

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:32:46