问题 使用nullptr_t时,为什么会出现“参数设置但未使用”警告?


我有一个自定义类实现 operator== 同 nullptr

这是我的代码愚蠢到一个简单的例子:

#include <cstdint>
#include <iostream>

class C {
private:
    void *v = nullptr;

public:
    explicit C(void *ptr) : v(ptr) { }

    bool operator==(std::nullptr_t n) const {
        return this->v == n;
    }
};

int main()
{
    uint32_t x = 0;
    C c(&x);
    std::cout << (c == nullptr ? "yes" : "no") << std::endl;

    C c2(nullptr);
    std::cout << (c2 == nullptr ? "yes" : "no") << std::endl;


    return 0;
}

代码按预期工作,但g ++(版本6.2.1)给出了以下警告:

[Timur@Timur-Zenbook misc]$ g++ aaa.cpp -o aaa -Wall -Wextra
aaa.cpp: In member function ‘bool C::operator==(std::nullptr_t) const’:
aaa.cpp:12:36: warning: parameter ‘n’ set but not used [-Wunused-but-set-parameter]
     bool operator==(std::nullptr_t n) const {
                                    ^

我究竟做错了什么?

注意:我正在使用 -Wall -Wextra


10463
2017-11-24 15:38


起源

@SamVarshavchik尝试-Wall -Wextra。可在wandbox 6.1上重现: melpon.org/wandbox/permlink/OGeniUkFzE8dRP1v - krzaq
有趣。请注意,您可以进一步减弱它: #include <iostream> int main() { std::nullptr_t n = nullptr; if (n == nullptr) std::cout << "yes"; } - Christian Hackl
@wasthishelpful:也许GCC在这里产生警告是正确的,但措辞 “参数设置但未使用” 当然还有很多不足之处。 - Christian Hackl
添加 n=n; 该功能使警告消失。看起来编译器知道这一点 n 可 NULL,并简单地优化对它的引用,然后最终产生警告。 - Sam Varshavchik
l值的左值到右值的转换 nullptr_t 对象不访问其存储的值。无论如何应该提交一个bug。 - T.C.


答案:


对于为什么会发生这种情况并不是一个真正的答案,但无论如何都有价值 n 但 nullptr

返回 this->v == nullptr 并使参数unnamed删除警告:

bool operator==(std::nullptr_t) const {
    return this->v == nullptr;
}

编辑:

声明 n 作为右值引用,或作为const左值引用也会删除警告:

bool operator==(std::nullptr_t&& n) const {
    return this->v == n;
}

bool operator==(const std::nullptr_t& n) const {
    return this->v == n;
}

EDIT2:

有关使用未使用变量的警告的更多方法可以在以下位置找到 这个问题 (请将@ShafikYaghmour指向评论中)。上面的例子涵盖了“隐含”的方式。

可以使用显式解决方案,但由于有效地使用了参数,因此IMHO看起来不那么连贯。测试的显式解决方案包括:

bool operator==(std::nullptr_t n) const {
    (void)n;
    return this->v == n;
}

#define UNUSED(expr) do { (void)(expr); } while (0)

bool operator==(std::nullptr_t n) const {
    UNUSED(n);
    return this->v == n;
}

GCC的非便携式解决方案:

bool operator==(__attribute__((unused)) std::nullptr_t n) const {
    return this->v == n;
}

9
2017-11-24 15:53



如果它不是答案,那么IMO应该是评论。 - Christian Hackl
我其实相信这一点 是 一个答案,因为它提供了一种非常合理的方法来避免警告。使用类型对象的标识符 std::nullptr_t 是没有意义的。 - Angew
我同意,这是一个有效的答案。 - Sam Varshavchik
但是,这种情况可能发生在模板中 std::nullptr_t 实际上是一个类型参数。 - Christian Hackl
我对这个答案有疑问。如果我删除参数名称只是比较 nullptr:如果有人将非null指针强制转换为什么呢 nullptr_t? - Venemo