Explain `_Generic` error message: error: invalid type argument of unary '`*`' (have '`int`')
Explain `_Generic` error message: error: invalid type argument of unary '`*`' (have '`int`')
我通常不需要帮助来理解错误消息,但是这个看起来一定是一个错误。我梳理了 "questions that may already have your answer",但其中 none 似乎使用了 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 错误消息是:
error: invalid type argument of unary '*
' (have 'int
')
note: in expansion of macro 'foo
'
clang 发出类似含义的消息:
fatal error: indirection requires pointer operand ('int
' invalid)
note: expanded from macro 'foo
'
这些消息似乎暗示了以下内容之一:
- 编译器从
int *
泛型关联中选择表达式。
- 通用关联的表达式均已求值。
C11§6.5.1.1p3 似乎明确禁止这两种解释:
The controlling expression of a generic selection is not evaluated. If a generic selection has a generic association with a type name that is compatible with the type of the controlling expression, then the result expression of the generic selection is the expression in that generic association. Otherwise, the result expression of the generic selection is the expression in the default generic association. None of the expressions from any other generic association of the generic selection is evaluated.
任何人都可以为我解释一下这个错误消息吗?
编译器是正确的:sizeof *(42)
是一个约束违规,因为它将 *
应用于整数类型的表达式。现在 _Generic
的一件事很重要,它不是经过预处理时间处理的,而是作为 C 语言意义上的适当表达式(具有最高优先级)处理的。这个 _Generic
表达式的效果实际上与做类似
的效果相同
(1 ? sizeof (42) : sizeof *(42))
在这里你知道第二个分支从未被评估过,仍然没有人期望它能编译。
我通常不需要帮助来理解错误消息,但是这个看起来一定是一个错误。我梳理了 "questions that may already have your answer",但其中 none 似乎使用了 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 错误消息是:
error: invalid type argument of unary '
*
' (have 'int
')note: in expansion of macro '
foo
'
clang 发出类似含义的消息:
fatal error: indirection requires pointer operand ('
int
' invalid)note: expanded from macro '
foo
'
这些消息似乎暗示了以下内容之一:
- 编译器从
int *
泛型关联中选择表达式。 - 通用关联的表达式均已求值。
C11§6.5.1.1p3 似乎明确禁止这两种解释:
The controlling expression of a generic selection is not evaluated. If a generic selection has a generic association with a type name that is compatible with the type of the controlling expression, then the result expression of the generic selection is the expression in that generic association. Otherwise, the result expression of the generic selection is the expression in the default generic association. None of the expressions from any other generic association of the generic selection is evaluated.
任何人都可以为我解释一下这个错误消息吗?
编译器是正确的:sizeof *(42)
是一个约束违规,因为它将 *
应用于整数类型的表达式。现在 _Generic
的一件事很重要,它不是经过预处理时间处理的,而是作为 C 语言意义上的适当表达式(具有最高优先级)处理的。这个 _Generic
表达式的效果实际上与做类似
(1 ? sizeof (42) : sizeof *(42))
在这里你知道第二个分支从未被评估过,仍然没有人期望它能编译。