Va_list, va_start, and (A *) 0)->

Source: Internet
Author: User

C functions are written from right to left into the stack.

Va_list AP; // = char * AP; (one character pointer)

In va_start (AP, V) (AP = (va_list) _ addressof (v) + _ intsizeof (v )) // return the address of the parameter list after parameter V (V address + V length)

Va_arg (AG, type): va_arg (AP, t) (* (T *) (AP + = _ intsizeof (t)-_ intsizeof (t ))) // obtain the value of the specified type int I = va_arg (AP, INT) and direct the AP to a parameter

Va_end (AG): clears the parameter list. AG is invalid when the parallel parameter pointer is set. Note: After the pointer AG is set to invalid, you can call va_start () and va_arg to restore Arg. Each time va_start ()/va_arg () is called, a corresponding va_end () must match it. The parameter pointer can be freely moved back and forth in the parameter list, but must be in va_start ()... Within va_end ()

Note:

Where: # DEFINE _ intsizeof (N) (sizeof (n) + sizeof (INT)-1 )&~ (Sizeof (INT)-1)

~ It indicates bitwise inversion. _ Intsizeof (n) converts the length of N to an integer multiple of the int length.

For example, if n is 5, the binary value is 101b, the int length is 4, and the binary value is 100b, the integer multiple of N to the int length is 8. (5 + 4-1)/4) * 4 = 8;

~ (Sizeof (INT)-1) is ~ (4-1) = ~ (100000011b) = 11111100b, so that any number &~ (Sizeof (INT)-1) the last two digits must be 0, which is definitely an integer multiple of 4.

(Sizeof (n) + sizeof (INT)-1) is to increase the number of numbers greater than 4 m but less than or equal to 4 (m + 1) to greater than or equal to 4 (m + 1) but smaller than 4 (m + 2), then &~ (Sizeof (INT)-1). Then, the original length is exactly a multiple of 4.

That is:

(5 + 4-1)/4)

(Sizeof (n) + sizeof (INT)-1 )&~ (Int-1)

 

High stack address
| .......
| Function return address
| .......
| Last function parameter
| ....
| The first variable parameter of the function <-- after va_start, the AP points
| Last fixed parameter of the Function
| The first fixed parameter of the Function
Stack top and low address

In the Linux kernel, two very clever macros are used for implementation. One is the offsetof macro and the other is the container_of macro. The two macros are described below.

1. offsetof macro [Definition]: # define offsetof (type, member) (size_t) & (type *) 0)-> member [function ]: obtains the offset of a struct variable Member in this struct. [Example]: struct a {int X; int y; int Z ;}; void main () {printf ("the offset of Z is % d", offsetof (struct, z);} // The output result is 8 [Analysis]: The macro, type is the struct type, and member is the variable name in the structure. (Type *) 0) indicates that the spoofing compiler has a pointer to the structure type, and its address value is 0 (type *) 0) -> member is the address for obtaining the member variable member in the struct type. because the base address is 0, the Member Address is of course the offset of member in type.

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.