结构类型的完成是否对同一范围内该类型的所有先前声明有效?
Is the completing of a structure type valid for all prior declarations of that type at the same scope?
标准先声明(强调我的):
"An array type of unknown size is an incomplete type. It is completed, for an identifier of that type,by specifying the size in a later declaration (with internal or external linkage). A structure or union type of unknown content (as described in 6.7.2.3) is an incomplete type. It is completed, for all declarations of that type, by declaring the same structure or union tag with its defining content later in the same scope."
Source: C18, §6.2.5/22
但后来它说(强调我的):
"All declarations of structure, union, or enumerated types that have the same scope and use the same tag declare the same type. Irrespective of whether there is a tag or what other declarations of the type are in the same translation unit, the type is incomplete132) until immediately after the closing brace of the list defining the content, and complete thereafter.
132) An incomplete type can only be used when the size of an object of that type is not needed. It is not needed, for example, when a typedef name is declared to be a specifier for a structure or union, or when a pointer to or a function returning a structure or union is being declared. (See incomplete types in 6.2.5.) The specification has to be complete before such a function is called or defined."
Source: C18, §6.7.2.3/4
这不是自相矛盾吗?
首先它说,后来完成的结构声明对于该类型的所有 声明有效,包括先前的声明。因此,恕我直言,事先声明应表示完整的结构类型。
但是后来又说,类型的补全只有在定义声明中定义内容的列表的右大括号之后才有效。
- 现在对的是什么?
示例测试:
#include <stdio.h>
struct foo; // prior declaration of struct foo.
int main (void)
{
struct foo bar;
//printf("%zu", sizeof(bar));
}
struct foo { // declaration of foo with defined content.
int x;
char y[4];
};
编译器在编译这段代码时抛出错误:
海湾合作委员会:
"7:16: error: storage size of 'bar' isn't known"
叮当声:
"7:16: error: variable has incomplete type 'struct foo'"
因此,它们似乎是按照后面的引用实施的。
- 但这不是错误的,或者至少不是严格意义上的 standard-compliant/correct,因为标准规定在同一范围内,在后面的声明中完成的结构类型应该对前面的结构类型有效?
非常感谢引用标准的推理。
我看不出有什么矛盾。
First it says, that the later completed declaration of a structure is
valid for all declarations of that type, including the prior ones.
Thus, a prior declaration shall IMHO denote a complete structure type.
先前的声明不表示完整的类型。该类型只有在定义了一个结构点之后才变得完整。
考虑以下示例
#include <stdio.h>
struct A;
int main(void)
{
// printf( "sizeof( struct A ) = %zu\n", sizeof( struct A ) );
extern struct A { int x; } a;
printf( "sizeof( struct A ) = %zu\n", sizeof( a ) );
return 0;
}
如果取消对 printf
的第一次调用的注释,编译器将发出错误,因为此时结构 A 的定义未知。
标准先声明(强调我的):
"An array type of unknown size is an incomplete type. It is completed, for an identifier of that type,by specifying the size in a later declaration (with internal or external linkage). A structure or union type of unknown content (as described in 6.7.2.3) is an incomplete type. It is completed, for all declarations of that type, by declaring the same structure or union tag with its defining content later in the same scope."
Source: C18, §6.2.5/22
但后来它说(强调我的):
"All declarations of structure, union, or enumerated types that have the same scope and use the same tag declare the same type. Irrespective of whether there is a tag or what other declarations of the type are in the same translation unit, the type is incomplete132) until immediately after the closing brace of the list defining the content, and complete thereafter.
132) An incomplete type can only be used when the size of an object of that type is not needed. It is not needed, for example, when a typedef name is declared to be a specifier for a structure or union, or when a pointer to or a function returning a structure or union is being declared. (See incomplete types in 6.2.5.) The specification has to be complete before such a function is called or defined."
Source: C18, §6.7.2.3/4
这不是自相矛盾吗?
首先它说,后来完成的结构声明对于该类型的所有 声明有效,包括先前的声明。因此,恕我直言,事先声明应表示完整的结构类型。
但是后来又说,类型的补全只有在定义声明中定义内容的列表的右大括号之后才有效。
- 现在对的是什么?
示例测试:
#include <stdio.h>
struct foo; // prior declaration of struct foo.
int main (void)
{
struct foo bar;
//printf("%zu", sizeof(bar));
}
struct foo { // declaration of foo with defined content.
int x;
char y[4];
};
编译器在编译这段代码时抛出错误:
海湾合作委员会:
"7:16: error: storage size of 'bar' isn't known"
叮当声:
"7:16: error: variable has incomplete type 'struct foo'"
因此,它们似乎是按照后面的引用实施的。
- 但这不是错误的,或者至少不是严格意义上的 standard-compliant/correct,因为标准规定在同一范围内,在后面的声明中完成的结构类型应该对前面的结构类型有效?
非常感谢引用标准的推理。
我看不出有什么矛盾。
First it says, that the later completed declaration of a structure is valid for all declarations of that type, including the prior ones. Thus, a prior declaration shall IMHO denote a complete structure type.
先前的声明不表示完整的类型。该类型只有在定义了一个结构点之后才变得完整。
考虑以下示例
#include <stdio.h>
struct A;
int main(void)
{
// printf( "sizeof( struct A ) = %zu\n", sizeof( struct A ) );
extern struct A { int x; } a;
printf( "sizeof( struct A ) = %zu\n", sizeof( a ) );
return 0;
}
如果取消对 printf
的第一次调用的注释,编译器将发出错误,因为此时结构 A 的定义未知。