>-"Understanding function declaration"

Source: Internet
Author: User

<C traps and defects> -- "Understanding function declaration"

Once, a programmer talked to me about a problem. He was writing a C program that runs independently on a microprocessor. When the computer starts, the hardware calls the child routine with the first address 0. To simulate startup, we must design a C statement to explicitly call the routine. After a period of thinking, we finally get the following statement:

(* (Void (*) () 0 )();

An expression like this may make every C programmer feel "chilling ". However, they don't have to worry about it, because there is only one simple rule to construct such expressions: to declare them in the way they are used.

The declaration of any c variable consists of two parts: type and a set of declarations similar to expressions (declarator ). On the surface, the Declaration is similar to the expression. evaluate it and return a result of the given type in the Declaration. The simplest declaration Operator is a single variable. For example:

Float F, G;

The meaning of this statement is: when the expression F and G are evaluated, the type of the expression F and G is float ). Because the declaration Operator is similar to the expression, we can also use any brackets in the declaration Operator:

Float (f ));

The meaning of this statement is: when the value is evaluated, the (f) type is a floating point type, which can be inferred that F is also a floating point type.

The same logic applies to declarations of function and pointer types, for example:

Float ff ();

The meaning of this statement is: The expression ff () returns a floating point number, that is, FF is a function that returns a floating point dung type. Similarly,

Float * PF;

This statement indicates that * PF is a floating point number, that is,. PF is a pointer to a floating point number.

These forms can also be combined in the declaration, just as in the expression. Therefore,

Float * g (), (* H )();

* G () and (* H) () are floating point expressions. Because the combination priority of () is higher than *, g () is * (G (): G is a function, and the return value type of this function is a pointer to a floating point. Similarly, we can conclude that H is a function pointer, And the return value of H pointing to the function is a floating point type.

Once we know how to declare a variable of a given type, the type conversion operator of this type is easy to get: just remove the variable name and semicolon at the end of the Declaration in the Declaration, then, encapsulate the remaining parts with a bracket. For example, because of the following statement:

Float (* H )();

Indicates that H is a pointer to a function with a return value of the floating point type. Therefore,

(Float (*)());

It is a type conversion character that refers to a pointer to a function with a return value of the floating point type.

With these preparations, we can now analyze the expression (* (void (*) () 0) () in two steps )().

Step 1: assuming that the variable FP is a function pointer, how can we call the function that FP points? The call method is as follows:

(* FP )();

Because FP is a function pointer, * FP is the function pointed to by this pointer, so (* FP) () is the method to call this function. The ansic standard allows programmers to abbreviated the above formula as FP (), but remember that this method is just a short form.

In the expression (* FP) (), * brackets on both sides of the FP are very important because the priority of the function operator () is higher than that of the single object operator *. If * FP has no parentheses on both sides, * FP () actually has exactly the same meaning as * (FP (). ansic regards it as * (* FP )()).

Now, the problem is to find an appropriate expression to replace FP. We will solve this problem in step 2 of the analysis. If the C compiler can understand the types in our brains, we can write as follows:

(* 0 )();

The preceding formula does not take effect, because the operator * must have a pointer for the operand. In addition, this pointer should also be a function pointer so that the result after the operator * can be called as a function. Therefore, type conversion must be performed on 0 in the above formula. The converted type can be roughly described as: "pointer to function with return value of void type ".

If FP is a pointer to a function whose return value is void, the value of (* FP) () is void. The FP declaration is as follows:

Void (* FP )();

Therefore, we can use the following method to call a subroutine whose storage location is 0:

Void (* FP )();

(* FP )();

Note: FP is initialized to 0 by default.

The cost of this writing is to declare a "dumb" variable.

However, once we know how to declare a variable, we naturally know how to convert the type of a constant to the type of the variable: you only need to remove the variable name from the variable declaration.

Therefore, the constant 0 is converted to the "pointer to the function whose return value is void" type, which can be written as follows:

(Void (*) () 0;

Therefore, we can replace FP with (void (*) () 0 to get:

(Void (*) () 0 )();

The semicolon at the end makes the expression a statement.

When I first solved this problem, there was no typedef statement in C language. Although typedef is not used to solve this problem, it is a good way to analyze the details of this example, but it is clear to use typedef to make the statement clearer:

Typedef void (* function )();

(* (Function) 0 )();

 

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.