From a friend's blog, we can see an interesting pen question:
Struct s {
Int;
Int B;
Char C [8];
Void * D;
} Mystruct;
1. Q & (struct s *) 0-> D. Is the result set?
2. Under what circumstances does this type of code usually occur?
The answer is:
1. 16.
2. Used to take the offset of elements in the structure.
This is the first time that we can see the offset of elements in the structure. To better understand it, let's take a closer look at what is going on.
First of all, 0 represents null. When it comes to pointers, null is always terrible, but it is exceptionally safe. What is the problem? Here 0 is a constant. If it is changed to another constant (such as a String constant), will the output result be returned if it is changed to an uninitialized variable? How does the compiler handle it?
Here we use the-> operator. Can I replace it with the. Operator? -> What are the differences between the. operator and the. Operator when the compiler generates code? The struct here is special and does not require the compiler to align the memory address. What kind of performance will this Code show for non-standard struct, class, union, and enum? What about nested strict?
So I wrote the following test code:
# Include <stdio. h>
Struct s {
Int;
Int B;
Char C [8];
Void * D;
} Mystruct;
Struct alignmem {
Char ch;
Int I;
Double F;
};
Struct nested {
Int I;
Char ch;
Struct alignmem;
Struct {
Int N;
Char cc;
} Test;
};
# Define P (exp) printf ("% 30 s:/T % x/n", # exp, exp)
Int main (){
Int I;
P (& (struct s *) 0)-> D );
P (& (struct s *) 1)-> D );
P (& (struct s *) null)-> D );
P (& (struct s *) 10)-> D );
P (struct s *) null );
P (struct s *) 1 );
Printf ("I is a local variable without initialized:/N ");
P (struct s *) & I ));
P (& (struct s *) & I)-> D );
I = 0;
Printf ("I is initialized to 0:/N ");
P (& (struct s *) & I)-> D );
I = 1;
Printf ("I is initialized to 1:/N ");
P (& (struct s *) & I)-> D );
Printf ("const char [] as argument:/N ");
P (& (struct s *) "A")-> D );
Printf ("alignmen:/N ");
P (& (struct alignmem *) 0)-> F );
Printf ("nested:/N ");
P (& (struct nested *) 0)-> test. CC );
Return 0;
}
To see how the compiler handles the issue, you need to check the compilation code generated by the compiler. Here, the compiler uses VC 6.0. Compile with the following command in the command line:
CL/faasm.txt/FACS/fmmap.txt/tctest. cpp
/FA indicates the generation of assembly code,/FACS indicates that the generated assembly code includes machine commands and source code, And/TC indicates that the C language compiler is mandatory instead of the C ++ compiler.
Run test.exe and the output result is as follows:
& (Struct s *) 0)-> D: 10
& (Struct s *) 1)-> D: 11
& (Struct s *) null)-> D: 10
& (Struct s *) 10)-> D: 1A
(Struct s *) NULL: 0
(Struct s *) 1: 1
I is a local variable without initialized:
(Struct s *) & I): 12ff7c
& (Struct s *) & I)-> D: 12ff8c
I is initialized to 0:
& (Struct s *) & I)-> D: 12ff8c
I is initialized to 1:
& (Struct s *) & I)-> D: 12ff8c
Const char [] as argument:
& (Struct s *) "A")-> D: 4071f0
Alignmen:
& (Struct alignmem *) 0)-> F: 8
Nested:
& (Struct nested *) 0)-> test. CC: 1c
In the test results, I feel that this is something about the compiler rather than the language. In addition, this should be a good compiler. If there is an address above and the output is related to the memory address, you must perform a subtraction operation to get the offset address. If there is no address, the result is a "Net" volume.
The compiler maintains information about types. From the generated assembly code, we can also see that all statements such as (struct s *) 0 are determined during compilation, and when I is used, are determined at runtime.
In any case, this question is too much for people to learn.