Does a language feature allow the compiler to check the type of a variable in memory, or is type checking based only on the keyword used for the variable type?
For example:
unsigned short n = 3;
int *p = &n;
Both int and short use 4 bytes in memory, but the compiler cannot implicitly convert from a short * to an int *. How does the compiler know that n isn't a valid address for p in this case?
Does a language feature allow the compiler to check the type of a variable in memory, or is type checking based only on the keyword used for the variable type?
This is a very confused question. The compiler is the thing that implements the language. Therefore a language feature might require the compiler to do certain things (in order to make the feature work), but it doesn't allow the compiler to do things.
A "variable in memory" is a run-time concept. The compiler is only involved at compile time: It translates code in some language (the source language) into another language (the target language, typically assembler code / machine code). It emits instructions that (when executed) reserve memory and use this memory to store values. But at run-time, when the program is actually executed, the compiler is no longer part of the picture, so it can't check anything.
In C, types are checked at compile time. The compiler knows the types of literals (e.g. 42
is an int
and "hello"
is a char [6]
), and it knows the type of everything you declare (because it has to parse the declarations), including variables. Type checking and type conversion rules are unrelated to the sizes of types.
For example:
short int a = 42;
double b = a; // OK, even though commonly sizeof a == 2 and sizeof b == 8
On the other hand:
signed char c;
char *p = &c; // error, even though commonly char and signed char have the same
// size, representation, and range of possible values
It is perfectly possible to type-check C without actually generating any code.