[[nodiscard]] 到一个函数指针

[[nodiscard]] to a function pointer

我想使用第三方函数,它通过充满函数指针的结构提供 API。例如:

struct S {
    using p_func1 = int(*)(int, int);
    p_func1 func1;
    using p_func2 = int(*)(char*);
    p_func2 func2;
}

第三方库初始化这个结构。 需要检查这些函数(func1、func2)的 return 值,我希望我能以某种方式在 [[discard]] 属性上显示以确保检查 return 值。

有没有办法做到这一点,同时保持结构的 ABI?

编辑: 到目前为止,我能想到的最好的办法就是拥有另一个结构,如下所示:

struct S_wrap {
    S orig;
    [[nodiscard]] int func1(int a, int b){ return orig.func1(a, b); }
    [[nodiscard]] int func2(char* a){ return orig.func2(a); }
}

我希望有更好的东西

您的包装器(或任何包装器)是唯一的出路。该属性适用于函数 declarator-id(它的名称),而不是函数的类型。所以在使用指针的时候就丢失了,也不能应用到指针本身:

[dcl.attr.nodiscard]

1 The attribute-token nodiscard may be applied to the declarator-id in a function declaration or to the declaration of a class or enumeration. It shall appear at most once in each attribute-list and no attribute-argument-clause shall be present.

因此,如果函数指针返回 int,防止丢弃结果的唯一方法是使用某种带有具有属性的命名函数(或 operator())的包装器应用。

如果您使用的是 GCC,则可以改用 __attribute__((warn_unused_result))。与 [[nodiscard]] 不同,它确实适用于 typedefusing:

struct S2 {
    using p_func1 = __attribute__((warn_unused_result)) int(*)(int, int);
    p_func1 func1;
    using p_func2 = __attribute__((warn_unused_result)) int(*)(char*);
    p_func2 func2;
};

有趣的是,Clang 接受此代码但不使用该属性并且不会发出警告。另外,它要求 __attribute__ 放在前面(如上),放在最后时会拒绝,在 ;.

之前

您可以使用 [[gnu::warn_unused_result]] 来更进一步:

struct S {
    using p_func1 = int(*)(int, int) [[gnu::warn_unused_result]];
    p_func1 func1;
    using p_func2 = int(*)(char*) [[gnu::warn_unused_result]];
    p_func2 func2;
};

使用 GCC,您可以将 [[gnu::warn_unused_result]] 放在末尾(如上所示)或开头:

using p_func1 = [[gnu::warn_unused_result]] int(*)(int, int);

就像在函数上使用 [[nodiscard]] 一样。但是,Clang 和 MSVC(可能还有其他)将拒绝第二种形式。对于第一种形式,Clang 会警告忽略的属性,因为它应用于类型。

在此处查看完整示例:https://godbolt.org/z/qEfEeoqeM