Static typing is very often misunderstood to mean that values are associated with types at Compile Time, when instead it means that that a Reference Value is manifestly (which is not the same as at Compile Time) constrained with respect to the type of the value it can denote, and that the language implementation, whether it is a compiler or an interpreter, both enforces and uses these constraints as much as possible.
An example of the use of static (manifest) type constraint by the is the ability to allocate exactly the right amount of memory to a variable, and another is the ability to disambiguate overloaded function calls in many cases.
Some languages allow associating constraints other than type based ones on the values that may be denoted by a reference, but this is uncommon.
Type Inference makes many/most/all type declarations unnecessary if the Type System of your Programming Language is strong enough.
However even when not necessary, type constraints can be very valuable in documenting assumptions and intentions.
Static typing is often confused with Strong Typing. Also see Dynamic Typing and Soft Typing.
It's worth noting that modern hardware is somewhat statically typed. In particular, the set of operations that can be done on a value (defining that variable's type) depends on the variable that refers to it. i.e:
I can do fadd $f0, $f1, $f2, which means that $fN is a floating point value.
I can do addi $r1, $r2, 3, which means that $rN is an integral value.
I can NOT do fadd $r1, $r2, $r3, or addi $f0, $f1, 3... (you CAN do this on the OpenRISC architecture, however.)
Now, there are few hardware-defined types on most platforms. Integer and address are often the same hardware type; segments are sometimes their own type, when they exist; floats are usually their own; vectors are their own type (or multiple types on x86). --Adam Berger
Languages or compilers that use static typing:
See original on c2.com