Data types are a way to convey information about an object or variable in a computer program. The information provided by data types is
- How much storage does an object of this type occupy
- What sub-elements, if any, does such an object have and by what names can these sub-elements be accessed
- What operations can be performed on an object of this type
There are two ways that types can be handled by a compiler/interpreter, statically and dynamically. How each type is handled depends on the definition of the programming language and the implementation of the compiler/interpreter.
With static types, the compiler (these types are mostly used in compiled languages) knows at any point in the program exactly which operations are valid for a given variable/object and, if you invoke an operation, which instructions to generate or which exact function to invoke. The runtime environment does not need any access to type information.
With dynamic types, the compiler/interpreter may roughly know what operations are valid for a given variable/object, but it may not know all the details. For example, the compiler knows that variable X is of type A or a sub-class of A, but it may not know exactly which sub-class. In this case, some type information must be accessed by the runtime environment to invoke the correct function of the correct sub-class.
In C, all types are static. All type information is handled by the compiler and there is no type information stored in the executables.
In Python, all types are defined as classes and they are in principle dynamic and it is likely that type information gets stored along with the actual data. This type information makes it possible to determine (at a later time) what exact kind of data was stored in a
An example of a language that uses both static and dynamic types would be C++. There, most types are handled statically, except for classes that contain virtual members. Those are handled dynamically.