在这个声明中
rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?
变量名rofl
掩盖了typedef名rofl
。因此在sizeof运算符中使用了指针rofl
,即表达式的类型为int *
。
对于该声明也是一样的。
rofl * rofl = malloc(sizeof *rofl);
除了使用具有类型为int
的typedef名称rofl
的解除引用指针rofl
表达式之外,似乎存在某些混淆。
这似乎是由于C语法定义引起的。
sizeof unary-expression
sizeof ( type-name )
然而,unary-expression
可以是一个被圆括号包含的基本表达式。
引自C标准(6.5.1 基本表达式)。
primary-expression:
( expression )
//...
例如,如果x
是一个变量的名称,那么您可以写成下面两种方式之一:
sizeof x
或者
sizeof( x )
为了清晰明了起见,您可以在sizeof运算符和主表达式之间插入空格。
sizeof ( x )
operator primary expression
假设我们要进行比较,考虑另一个一元运算符:正号。例如,你可以这样写:
+ x
或者
+ ( x )
现在只需将一元加号替换为另一个一元运算符sizeof
。
至于隐藏名称的问题,对于结构、联合和枚举来说是可以解决的,因为它们的名称中包含用于标记的关键字。
例如:
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( struct rofl));
}
在使用 sizeof 运算符的这个函数中,使用了类型名称为 struct rofl
的结构体。
而在这个函数中
typedef struct rofl { int x; } rofl;
void test(void) {
rofl * rofl = malloc(sizeof( rofl));
}
使用 sizeof
运算符时,需要使用变量 rofl
的原始表达式,该变量的类型为 struct rofl *
。
sizeof
是一个运算符而不是函数,所以括号只是多余的。 - user207421sizeof
操作数只有一个选项:它必须是某种“一元表达式”,因此不能是 typedef 名称。关于第一个问题,括号并不会导致编译器需要 typedef 名称。如果括号中只是一个标识符,则在该点上只能有效地是一个 typedef、函数或对象的名称,因此编译器只会找到一个解决方案;它不需要选择。 - Eric Postpischilsizeof (foo)
可以匹配 C 标准第 6.5.3 条款中所示的 “sizeof
unary-expression” 或同一条款中的 “sizeof (
type-name)
”。然后,匹配取决于标识符的含义,而不是局部语法。如果没有括号,只有第一个选项可能。 - Eric Postpischil