C + + Fog Landscape article: Understanding C + + Complex declaration and Declaration resolution

Source: Internet
Author: User

In the process of learning C-series language, it is always a problem for beginners to understand the complex declarations of C + +. When I was a beginner, I was also deeply troubled by rote memorization of many rules. After reading "C expert Programming" , try to understand the compiler's point of view of C + + declaration resolution, and write code to concatenate this part of logic, and then see a lot of seemingly complex statements, but also can be well understood and digested.

1. Complex statements

You can occasionally see the following complex declarations when writing C + + code: float(*(*e[10])(int*))[5] . I think your first reaction must be:MMP. Although we do not have this extremely complex declarative logic in our actual work, we do not advocate the use of such statements. But learn to understand and parse this kind of complex declarative logic, you can better understand how the key words in C + + are organized, to express the logic, but also to better understand the use of the various keywords.

For example, before the author of an article in the use of the "C/C + + in the usage of the Const keyword," a summary of the use of landscape 3:const in the fog, the way to memorize the const keyword in the declaration of the Order to clarify the different logic. This approach is not only inefficient, but does not understand why different sequencing can have an impact on declarative logic. In this article, I try to take everyone to forget these formulas, from the compiler's point of view to understand how the compiler handles the logic of these statements, know that they know the reason why.

2. Priority rules

The declaration model is obscure, and the author simply counts the key words such as const,volatile, which involve the declaration model, about 10. What is more complicated is that the order of these keywords can be arbitrarily combined with parentheses in C/s + + and a "chemical reaction"that looks wonderful.

After summing up the rules, the complex model can be simplified into a unit that we can understand. So let's take a look at the precedence rules for the C + + declaration.

    • A declaration is parsed by an identifier, that is, its name.
    • After the declaration is obtained, the following priority levels are installed to process the claims in turn:
      1. Prioritize the declarative logic in the parentheses section.
      2. Prioritize postfix operators, such as [], ()
      3. Handle prefix operators, such as *,const
    • Subsequent declarations can be processed in turn from right to left.

Having mastered the above priority rules , we go back to the beginning of this article to raise a little chestnut

1.找到声明e,e将作为声明的名字。2.处理后缀操作符,也就是e代表的是一个容量为10的数组。3.回到前缀操作符,该数组存储的内容为指针。4.跳出括号,开始新的一轮的**优先级规则**,处理后缀操作符(),我们发现这个指针指向的是一个参数为int\*的函数。5.接着再次回到前缀操作符,所以这个函数返回值依然是一个指针。6.跳出括号,继续前文的逻辑,我们发现该指针指向了一个内容为float,容量为5的数组。通过上述栗子我们不难发现,对于声明的处理本质上是一个有限自动机的状态变化过程,所以编译器同样也是按照上述的规律来理解并处理程序的复杂声明的。了解了优先级规则,我们也就不难去实现一个简单的小程序**cdecl**来处理声明逻辑了。####3.简单的代码实现通过上述流程的说明,我们很容易想到可以用**栈**来保存声明标识符左边的内容,而名字右边的内容则依照优先级规则依次处理。(优先处理数组与函数)。* **先分类将要处理声明的种类,并且声明token类型来进行处理**

Enum Type_tag {identifier,qualifier,type,pointer,lparen,lbracket,rparen,rbracket};

struct Token {
Type_tag type;
string content;
};

* **不断读取token,并且压入栈中,直到读取到声明标识符**

void Read_to_first_identifer () {
GetToken ();
while (this_t.type! = IDENTIFIER) {
Token_stack.push (this_t);
GetToken ();
}

cout << this_t.content + " is ";gettoken();

}

* **按照优先级法则处理逻辑,先右后左,遇到括号弹出之后继续上述逻辑**

void Deal_with_declarator () {
Switch (this_t.type) {
Case Lbracket:deal_with_arrays ();
Case Lparen:deal_with_function_args ();
}

deal_with_pointers();while(!token_stack.empty()) {    if(token_stack.top().type == LPAREN) {        token_stack.pop();        gettoken();        deal_with_declarator();    } else {        cout << token_stack.top().content + " ";        token_stack.pop();    }}

}

* **处理数组类型的函数**

void Deal_with_arrays () {
while (This_t.type = = Lbracket) {
cout << "Array";
GetToken ();
if (IsDigit (This_t.content[0])) {
printf ("0....%d of", Atoi (This_t.content.c_str ())-1);
GetToken ();
}

    gettoken();}

}

* **处理函数类型的函数**

void Deal_with_function_args () {
while (this_t.type! = Rparen) {
GetToken ();
}
GetToken ();

cout << "function returning ";

}
```

So by concatenating the above code, we can simply complete a small program that parses the C + + declaration. Try this small program to parse the example presented by the author in this article:
The implementation of the full version of the code, the author placed on his own GitHub, need to be able to self-pickup. "C Expert Programming" also has a corresponding C language version, the need can also be used as a reference.

4. Summary

Tired of complex statements? Want to have a more friendly claim type? The external part of course is to elicit the positive article, the next I will see with you, C + + in order to simplify the declaration of the type system, made those efforts to more efficiently improve the productivity of programmers. A

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.