yairchu
yairchu

Reputation: 24774

Why do tuples not get unused variable warnings?

In the following example, compiling with -Wall, some of the unused variables are not warned about:

#include <tuple>

struct Foo
{
    int a, b;
};

struct Bar
{
    ~Bar() {}

    int a, b;
};

int three() { return 3; }

int main()
{
    Foo f0 {1, 2};
    Foo f1 {three(), 2};
    Bar b0 {1, 2};
    Bar b1 {three(), 2};
    std::tuple<int, int> p0 {1, 2};
    std::tuple<int, int> p1 {three(), 2};
}

Why don't these get warnings? Is there a way to mark the destructor of Bar such that it won't mask the warnings?

Upvotes: 8

Views: 469

Answers (1)

dfrib
dfrib

Reputation: 73186

The compiler will do its best to flag unused variables, but this is difficult for non-trivial types, and both Bar and std::tuple<int, int> are non-trivial.

static_assert(std::is_trivial_v<Foo>);
static_assert(!std::is_trivial_v<Bar>);
static_assert(!std::is_trivial_v<std::tuple<int, int>>);

As is described in

As the compiler cannot tell for sure in some cases, such as the ctor calling an external function, the only reasonable way of handling this I see is explicit tagging of types for which there should be an unused warning if only ctor/dtor are called for a variable. Here's my attempt at attribute warn_unused.

you could use GCC's warn_unused attribute if you want a -Wunused-variable to be emitted in case on the constructor and/or destructor of the variable of the non-trivial type is called.

struct __attribute__((warn_unused)) Bar {
    ~Bar() {}
    int a, b;
};

int main() {
    Bar b{1, 3}; // warning: unused variable 'b' [-Wunused-variable]
}

Upvotes: 7

Related Questions