Does typedef in C/C++ really create a NEW type by combining the compound type (e.g. int*)?

不打扰是莪最后的温柔 提交于 2019-11-29 14:20:00

"Synonym" does not mean "text replacement". ptype is not literally expanded to int * by the preprocessor or anything.

What it means is that you can do things like:

typedef int *ptype;
ptype a;
int *b;

a = b;   // OK

The assignment is valid because ptype and int * are the same type; there is no type conversion or cast required.

typedef simply lets you give a new name to an existing type. But that name combines every aspect of the existing type into an indivisible entity, such that e.g. ptype a, b; is equivalent to ptype a; ptype b; (and const ptype means "const pointer-to-int" because ptype means "pointer-to-int").

In other words, the new names created by typedef behave like built-in keywords as far as declaring things goes, but the actual types represented by those names are the same.

When cplusplus.com says that typedef doesn't create a new type, what they mean is that anywhere where you can use a value of ptype you can also use a value of type int* and vice-verse. So if you define a function that takes a ptype parameter, you can pass it an int* without any conversions being necessary.

That does not mean that a typedef is implemented as purely textual substitution like a #define would be.

Referring to C89, section 3.5, here's the reason that ptype v1 = 0, v2 = 0; is not equivalent to int *v1 = 0, v2 = 0;. Later versions of C and C++ were informed by C89 and are essentially the same in this respect.

In ptype v1 = 0, v2 = 0;, ptype is the "declaration-specifiers", and v1 = 0, v2 = 0 is the "init-declarator-list". Specifically, ptype is a "type-specifier" and even more specifically it's a "typedef-name". So, we're declaring two variables (v1 and v2) both of which have type ptype, which is another name for int*.

In int* v1 = 0, v2 = 0, int* is not the "declaration-specifiers", because that consists of a series of "type-specifier", "storage-class-specifier" and "type-qualifier". You can look up each of those in turn, but all put together they amount to a whole list of keywords like static or const, built-in type names, plus typedef and enum names and struct/union specifiers. They don't include the *, which is part of the syntax for a compound type. So in this case int is the "declaration-specifiers and *v1 = 0, v2 = 0 is the "init-declarator list". Once we break down the grammar of the "init-declarator list", the * applies only to v1, not to v2. That's why it defines one int* and one int.

Similarly you could write ptype *v1 = 0, v2 = 0;, which would define one pytpe* and one ptype. That is to say, one int** and one int*.

The grammar for const int * vs const ptype works out to a similar result -- in the former the const "type-qualifier" applies to the int but in the latter it applies to ptype.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!