I know the title seems quite stupid, but I think it's worth asking.
我知道标题看起来很愚蠢,但我认为这值得一提。
Take this declaration(or definition, maybe) for example:
以此声明(或定义,可能)为例:
_Thread_local long volatile static int _Atomic const long unsigned x = 10;
I used to consider long long
as a type, but if it's a type name, how can so many qualifiers be inserted into it?
我曾经认为long long是一个类型,但如果它是一个类型名称,那么如何插入这么多限定符呢?
So I consulted N1570 with this question, only to be more confused. It mentions some terms such as "type-specifier" and "type-qualifier", and I can't find long long
in "type specifiers", but isn't long long
a primitive type in C? There are so many books telling me so!
所以我用这个问题咨询了N1570,只是为了更加困惑。它提到了一些术语,如“类型说明符”和“类型限定符”,我在“类型说明符”中找不到多长时间,但在C中不长的原始类型?有这么多书告诉我了!
Clarifying not duplicate:
澄清不重复:
Yes, I saw an existing question deals with long int long
, but this question have something to do with qualifiers, and is in C.
是的,我看到一个现有的问题涉及long int long,但这个问题与限定符有关,并且在C中。
1 个解决方案
#1
17
If you read the right bits of the standard carefully enough, you find that the monster declaration in the question is valid, even if implausible.
如果你仔细阅读标准的正确位置,你会发现问题中的怪物声明是有效的,即使不可信。
The 'right bits' includes:
'正确位'包括:
6.2.5 Types
There are five standard signed integer types, designated as
signed char
,short int
,int
,long int
, andlong long int
. (These and other types may be designated in several additional ways, as described in 6.7.2.)有五种标准的有符号整数类型,指定为signed char,short int,int,long int和long long int。 (这些和其他类型可以用其他几种方式指定,如6.7.2中所述。)
…
...
For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword
unsigned
) that uses the same amount of storage (including sign information) and has the same alignment requirements.对于每个有符号整数类型,存在相应(但不同)的无符号整数类型(使用关键字unsigned指定),其使用相同数量的存储(包括符号信息)并具有相同的对齐要求。
6.7.2 Type specifiers
At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each struct declaration and type name. Each list of type specifiers shall be one of the following multisets (delimited by commas, when there is more than one multiset per item); the type specifiers may occur in any order, possibly intermixed with the other declaration specifiers.
每个声明中的声明说明符中应至少给出一个类型说明符,并在每个结构声明和类型名称的说明符限定符列表中给出。每个类型说明符列表应为以下多个集合之一(用逗号分隔,每个项目有多个多集);类型说明符可以按任何顺序出现,可能与其他声明说明符混合。
…
...
long long
,signed long long
,long long int
, orsigned long long int
- long long,signed long long,long long int,或signed long long int
unsigned long long
, orunsigned long long int
- unsigned long long,或unsigned long long int
Other declaration specifiers include storage classes (static
and _Thread_local
in the example), and type qualifiers (volatile
and _Atomic
).
其他声明说明符包括存储类(示例中为static和_Thread_local),以及类型限定符(volatile和_Atomic)。
6.7 Declarations
6.7 Declarations
6.7声明
Syntax
句法
declaration:
declaration-specifiers init-declarator-listopt ;
static_assert-declaration声明:declaration-specifiers init-declarator-listopt; static_assert声明
declaration-specifiers:
storage-class-specifier
declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
alignment-specifier declaration-specifiersoptdeclaration-specifiers:storage-class-specifier declaration-specifiersopt type-specifier declaration-specifiersopt type-qualifier declaration-specifiersopt function-specifier declaration-specifiersopt alignment-specifier declaration-specifiersopt
Also, as noted by Olaf in a comment:
另外,正如奥拉夫在评论中指出的那样:
6.11.5 Storage-class specifiers
The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.
在声明中声明说明符开头之外的存储类说明符的放置是一个过时的功能。
It is also eccentric to split up the integer type keywords (the type specifier). A more orthodox version of the declaration would be:
拆分整数类型关键字(类型说明符)也是古怪的。宣言的更正统版本是:
static _Thread_local _Atomic const volatile unsigned long long int x = 10;
(or it might drop the int
).
(或者它可能会掉落int)。
#1
17
If you read the right bits of the standard carefully enough, you find that the monster declaration in the question is valid, even if implausible.
如果你仔细阅读标准的正确位置,你会发现问题中的怪物声明是有效的,即使不可信。
The 'right bits' includes:
'正确位'包括:
6.2.5 Types
There are five standard signed integer types, designated as
signed char
,short int
,int
,long int
, andlong long int
. (These and other types may be designated in several additional ways, as described in 6.7.2.)有五种标准的有符号整数类型,指定为signed char,short int,int,long int和long long int。 (这些和其他类型可以用其他几种方式指定,如6.7.2中所述。)
…
...
For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword
unsigned
) that uses the same amount of storage (including sign information) and has the same alignment requirements.对于每个有符号整数类型,存在相应(但不同)的无符号整数类型(使用关键字unsigned指定),其使用相同数量的存储(包括符号信息)并具有相同的对齐要求。
6.7.2 Type specifiers
At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each struct declaration and type name. Each list of type specifiers shall be one of the following multisets (delimited by commas, when there is more than one multiset per item); the type specifiers may occur in any order, possibly intermixed with the other declaration specifiers.
每个声明中的声明说明符中应至少给出一个类型说明符,并在每个结构声明和类型名称的说明符限定符列表中给出。每个类型说明符列表应为以下多个集合之一(用逗号分隔,每个项目有多个多集);类型说明符可以按任何顺序出现,可能与其他声明说明符混合。
…
...
long long
,signed long long
,long long int
, orsigned long long int
- long long,signed long long,long long int,或signed long long int
unsigned long long
, orunsigned long long int
- unsigned long long,或unsigned long long int
Other declaration specifiers include storage classes (static
and _Thread_local
in the example), and type qualifiers (volatile
and _Atomic
).
其他声明说明符包括存储类(示例中为static和_Thread_local),以及类型限定符(volatile和_Atomic)。
6.7 Declarations
6.7 Declarations
6.7声明
Syntax
句法
declaration:
declaration-specifiers init-declarator-listopt ;
static_assert-declaration声明:declaration-specifiers init-declarator-listopt; static_assert声明
declaration-specifiers:
storage-class-specifier
declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
alignment-specifier declaration-specifiersoptdeclaration-specifiers:storage-class-specifier declaration-specifiersopt type-specifier declaration-specifiersopt type-qualifier declaration-specifiersopt function-specifier declaration-specifiersopt alignment-specifier declaration-specifiersopt
Also, as noted by Olaf in a comment:
另外,正如奥拉夫在评论中指出的那样:
6.11.5 Storage-class specifiers
The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.
在声明中声明说明符开头之外的存储类说明符的放置是一个过时的功能。
It is also eccentric to split up the integer type keywords (the type specifier). A more orthodox version of the declaration would be:
拆分整数类型关键字(类型说明符)也是古怪的。宣言的更正统版本是:
static _Thread_local _Atomic const volatile unsigned long long int x = 10;
(or it might drop the int
).
(或者它可能会掉落int)。