Variables
-
Each variable type is bits, but how does the compiler store them in machine code? Is the variable type like a tag that follows the number everywhere ( processor, memory, HDD etc. )?
-
Each variable type is bits, but how does the compiler store them in machine code? Is the variable type like a tag that follows the number everywhere ( processor, memory, HDD etc. )?
All memory is just bits and bytes. How one interprets the bytes is up to the user. If you open a file and write an integer to it, you'll store 4 bytes, which could be read in as 4 characters by some other program. There's no meta-information about what the data object (file, memory, etc) associated with a datum anywhere in the OS. At least that's true for Windows, DOS, Unix, Linux, VMS, etc. There may be some OS out there that does use meta-data to determine what type a particular datum has, but I'm not aware of it.
"A little song, a little dance, a little seltzer down your pants" Chuckles the clown
-
Each variable type is bits, but how does the compiler store them in machine code? Is the variable type like a tag that follows the number everywhere ( processor, memory, HDD etc. )?
To add just a bit more to the previous answer, in C/C++ you can even use the fact that memory is uniform, in other words there is no way of saying what is stored in a memory location. An
union
declaration is just a redefinition of the same memory area to be interpreted in different ways:union {
char ch[4];
int ival;
} s;//...
printf ("Size of union is %d\n", sizeof(s)); //should print "4"
s.ch[0] = 'A';
s.ch[1] = 'B';
s.ch[2] = 'C';
s.ch[4] = 'D';printf ("Integer value is 0x%x\n", s.ival); //should print 0x44434241 or 0x41424344
The results of the second printf depends of the endianness of the machine (little endian vs big endian).
Mircea (see my latest musings at neacsu.net)
-
To add just a bit more to the previous answer, in C/C++ you can even use the fact that memory is uniform, in other words there is no way of saying what is stored in a memory location. An
union
declaration is just a redefinition of the same memory area to be interpreted in different ways:union {
char ch[4];
int ival;
} s;//...
printf ("Size of union is %d\n", sizeof(s)); //should print "4"
s.ch[0] = 'A';
s.ch[1] = 'B';
s.ch[2] = 'C';
s.ch[4] = 'D';printf ("Integer value is 0x%x\n", s.ival); //should print 0x44434241 or 0x41424344
The results of the second printf depends of the endianness of the machine (little endian vs big endian).
Mircea (see my latest musings at neacsu.net)
I left out unions, since technically writing to one union member and reading from another in C/C++ invokes undefined behavior. [Undefined Behavior in C++](https://adriann.github.io/undefined\_behavior.html) Note that while the standard says that it is undefined behavior, I have not run into any compilers that this doesn't work, at least with POD. Use of constructed/destructed objects in a union is not something I've tried, but you can probably see that there may be issues if you want to have a union of std::string and std::vector, for example. Trying to write as a std::string and then read as a std::vector is almost certainly going to result in Bad Things™ occuring.
"A little song, a little dance, a little seltzer down your pants" Chuckles the clown
-
To add just a bit more to the previous answer, in C/C++ you can even use the fact that memory is uniform, in other words there is no way of saying what is stored in a memory location. An
union
declaration is just a redefinition of the same memory area to be interpreted in different ways:union {
char ch[4];
int ival;
} s;//...
printf ("Size of union is %d\n", sizeof(s)); //should print "4"
s.ch[0] = 'A';
s.ch[1] = 'B';
s.ch[2] = 'C';
s.ch[4] = 'D';printf ("Integer value is 0x%x\n", s.ival); //should print 0x44434241 or 0x41424344
The results of the second printf depends of the endianness of the machine (little endian vs big endian).
Mircea (see my latest musings at neacsu.net)
To add even more: Fpr class objects (instances), the compiler adds another "semi-hidden" field to hold a reference to the class definition object. The class definition is present at run time, and may be interrogated. The class definition is the type of the class instances. Second: A debugger knows the types of even primitive values. That is because the compiler (optionally) writes a lot of metadata to a separate file, or to separate sections of a linkable / executable file, called 'debug information'. The debug information is not loaded into RAM during normal execution. When a debugger is in control, when given an address in RAM, it can look up in the debug info what type of variable (or whatever) is located on that address. The lookup is not direct; interpreting the debug info is not a task for beginners!
Religious freedom is the freedom to say that two plus two make five.
-
To add even more: Fpr class objects (instances), the compiler adds another "semi-hidden" field to hold a reference to the class definition object. The class definition is present at run time, and may be interrogated. The class definition is the type of the class instances. Second: A debugger knows the types of even primitive values. That is because the compiler (optionally) writes a lot of metadata to a separate file, or to separate sections of a linkable / executable file, called 'debug information'. The debug information is not loaded into RAM during normal execution. When a debugger is in control, when given an address in RAM, it can look up in the debug info what type of variable (or whatever) is located on that address. The lookup is not direct; interpreting the debug info is not a task for beginners!
Religious freedom is the freedom to say that two plus two make five.
trønderen wrote:
class objects (instances), the compiler adds another "semi-hidden" field to hold a reference to the class definition object. The class definition is present at run time, and may be interrogated. The class definition is the type of the class instances.
With the small caveat that classes need at least one virtual function to get this RTTI (Run-Time Type Information). Classes without virtual function members don't get this vtable member. Pretty sure this is standard required behavior, but I haven't checked. It is true however at least in the case of MSVC, the compiler I know best.
Mircea (see my latest musings at neacsu.net)