【问题标题】:Explain `_Generic` error message: error: invalid type argument of unary '`*`' (have '`int`')解释`_Generic`错误消息:错误:一元'`*`'的无效类型参数(有'`int`')
【发布时间】:2015-12-15 01:14:21
【问题描述】:

我通常不需要帮助来理解错误消息,但是这似乎一定是一个错误。我已经梳理了“可能已经有你答案的问题”,但这些问题似乎都没有使用 C11 最近添加的_Generic 功能,所以我认为这可能是一个独特的问题。这是我的测试用例:

#include <stdio.h>
#define foo(bar) _Generic((bar), int:   sizeof (bar)   \
                               , int *: sizeof *(bar))

int main(void) {
    printf("%d\n", foo(42));
}

我看到的 gcc 5.2 错误消息如下:

错误:一元“*”的类型参数无效(有“int”)

注意:在宏'foo'的扩展中

clang 发出类似含义的消息:

致命错误:间接需要指针操作数('int' 无效)

注意:从宏“foo”扩展而来

这些消息似乎暗示以下之一:

  • 编译器从int * 泛型关联中选择了表达式。
  • 通用关联的表达式均已评估。

C11§6.5.1.1p3 似乎明确禁止这两种解释:

不评估通用选择的控制表达式。如果泛型选择具有与控制表达式的类型兼容的类型名称的泛型关联,则泛型选择的结果表达式是该泛型关联中的表达式。否则,泛型选择的结果表达式是默认泛型关联中的表达式。不会评估来自任何其他泛型选择的泛型关联的表达式。

谁能帮我解释一下这个错误信息?

【问题讨论】:

  • 我认为您误解了“已评估”一词。仅仅因为某些东西没有被评估并不意味着它可能是无效的 C 代码 (sizeof *(42))。
  • @cremno: sizeof *(42) 完全有效...
  • @BLUEPIXY 谢谢。我在重新格式化代码时错过了这一点(_Generic 以前都是一行)。我已经“修复”了问题中的代码,但错误仍然存​​在。
  • 看起来像this bug report。没有被接受,理由是类型检查与评估不同。
  • @KemyLand sizeof *(42) 完全有效this

标签: c generics gcc clang c11


【解决方案1】:

编译器是对的:sizeof *(42) 是违反约束的,因为它将* 应用于整数类型的表达式。现在_Generic 的一件事很重要,这不是在预处理时间处理,而是作为 C 语言意义上的正确表达式(具有最高优先级)。这个_Generic 表达式的效果实际上和做类似的事情一样

(1 ? sizeof (42) : sizeof *(42))

在这里你知道第二个分支永远不会被评估,仍然没有人期望它编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多