【问题标题】:Why is this generic expression bugging out? [duplicate]为什么这个通用表达式会出错? [复制]
【发布时间】:2016-02-26 09:27:47
【问题描述】:

最近我回答了一些question,询问如何实现结构成员的复杂const正确性。这样做我使用了通用表达式并遇到了奇怪的行为。下面是示例代码:

struct A
{
    union {
        char *m_ptrChar;

        const char *m_cptrChar;
    } ;
};

#define ptrChar_m(a) _Generic(a, struct A *: a->m_ptrChar,        \
                                 const struct A *: a->m_cptrChar,  \
                                 struct A: a.m_ptrChar,        \
                                 const struct A: a.m_cptrChar)

void f(const struct A *ptrA)
{
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!!
}

在 GCC 和 Clang 上,通用表达式选择 a 的类型必须为 struct A 的情况,这没有任何意义。当我评论最后两个案例时,虽然它工作正常。为什么会这样 - 是不是有什么错误?

关于 clang 的确切错误消息是:

test.c:17:5: error: member reference type 'const struct A *' is a pointer; did you mean to use '->'?
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!!
    ^
test.c:12:45: note: expanded from macro 'ptrChar_m'
                                 struct A: a.m_ptrCHar,        \
                                            ^
test.c:17:5: error: member reference type 'const struct A *' is a pointer; did you mean to use '->'?
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!!
    ^
test.c:13:51: note: expanded from macro 'ptrChar_m'
                                 const struct A: a.m_cptrChar)
                                                  ^
test.c:17:21: error: cannot assign to variable 'ptrA' with const-qualified type 'const struct A *'
    ptrChar_m(ptrA) = 'A'; // NOT DESIRED!!
                    ^
test.c:15:24: note: variable 'ptrA' declared const here
void f(const struct A *ptrA)
                       ^
test.c:23:18: error: invalid application of 'sizeof' to a function type [-Werror,-Wpointer-arith]
    return sizeof(main);
4 errors generated.

【问题讨论】:

  • 这是一个很好的问题,但是将编译器输出作为屏幕截图包含在内并不是那么好。您不能将文本复制粘贴到问题中吗?
  • THIS 可能会回答您的问题

标签: c generic-programming c11


【解决方案1】:

虽然不评估不匹配的选择,但编译器仍在编译代码。因此,不允许在指向结构的指针上使用. 运算符。

如果你的输入表达式总是一个变量,你可以取代表结构实例的变量的地址。

#define AptrChar_m(a) _Generic(a, struct A *: a->m_ptrChar, \
                                  const struct A *: a->m_cptrChar)
#define ptrChar_m(a) AptrChar_m(_Generic(a, struct A *: a, \
                                            const struct A *: a,  \
                                            struct A: &a,        \
                                            const struct A: &a))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 2017-01-22
    • 2018-10-09
    相关资源
    最近更新 更多