Using C besides the compiler, that perfectly well knows about the type of the given values there is no system that knows about the type of a given value.
Note that C by itself doesn't bring any runtime type information system with it.
Take a look at the following example:
int i_var;
double d_var;
int main () {
i_var = -23;
d_var = 0.1;
return 0;
}
In the code there are two different types of values involved one to be stored as an integer and one to be stored as a double value.
The compiler that analyzes the code pretty well knows about the exact types of both of them. Here the dump of a short fragment of the type information gcc held while generation code generated by passing the -fdump-tree-all
to gcc:
@1 type_decl name: @2 type: @3 srcp: <built-in>:0
chan: @4
@2 identifier_node strg: int lngt: 3
@3 integer_type name: @1 size: @5 algn: 32
prec: 32 sign: signed min : @6
max : @7
...
@5 integer_cst type: @11 low : 32
@6 integer_cst type: @3 high: -1 low : -2147483648
@7 integer_cst type: @3 low : 2147483647
...
@3805 var_decl name: @3810 type: @3 srcp: main.c:3
chan: @3811 size: @5 algn: 32
used: 1
...
@3810 identifier_node strg: i_var lngt: 5
Hunting down the @links you should clearly see that there really is a lot of information stored about memory-size, alignment-constraints and allowed min- and max-values for the type "int" stored in the nodes @1-3 and @5-7. (I left out the @4 node as the mentioned "chan" entry is just used to cha i n up any type definitions in the generated tree)
Reagarding the variable declared at main.c line 3 it is known, that it is holding a value of type int as seen by the type reference to node @3.
You'll sure be able to hunt down the double entries and the ones for d_var in an own experiment yourself if you don't trust me they will also there.
Taking a look at the generated assembler code (using gcc pass the -S
switch) listed we can take a look at the way the compiler used this information in code generation:
.file "main.c"
.comm i_var,4,4
.comm d_var,8,8
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $-23, i_var
fldl .LC0
fstpl d_var
movl $0, %eax
popl %ebp
ret
.size main, .-main
.section .rodata
.align 8
.LC0:
.long -1717986918
.long 1069128089
.ident "GCC: (Debian 4.4.5-8) 4.4.5"
.section .note.GNU-stack,"",@progbits
Taking a look at the assignment instructions you will see that the compiler figured out the right instructions "mov" to assign our int value and "fstp" to assign our "double" value.
Nevertheless besides the instructions chosen at the machine level there is no indication of the type of those values. Taking a look at the value stored at .LC0 the type "double" of the value 0.1 was even broken down in two consecutive storage locations each for a long to meet the known "types" of the assembler.
As a matter of fact breaking the value up this way was just one choice of other possiblities, using 8 consecutive values of "type" .byte would have done equally well.