Typedef is actually a declaration (it creates aliases for existing types), and is in no way limited to two 'parameters'. See Typedef Declarations (C) and Fundamental typedef operand syntax.
If you write typedef T;
, you are declaring T to be an unspecified type (called "no specified type" in the C89 spec). It's a little (and only a very little, but conceptually this might help you) like #define X
defines X
but the preprocessor will replace it with the empty string (i.e. remove X
).
So, you are typedef
ing T
to be unspecified, which makes the arguments to your swap
function of unspecified type.
What you are seeing here is that in C89 (but not C99, where it results in undefined behaviour - contrast ANSI 3.5.2 with ISOC99 6.7.2), unspecified types default to int
, which is why your method works for integers but not floats in Visual Studio (presumably it disallows implicit integer typing by default). GCC will compile it with floats, though, provided you aren't using -Werror
, which you probably should be.
I strongly suggest turning on some warnings: -Wall
in gcc will spit out the following, among other things
swap.c:1:9: warning: type defaults to ‘int’ in declaration of ‘T’ [-Wimplicit-int]
The reason it "works" on floats is because floats and ints are probably the same size (32 bits) on your machine. Try it with double. Or char. Or short.
swap
is really like this:
void swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
with you calling
swap((int*)&a, (int*)&b);
Try it and compare the results for yourself.
Edit: I just tried it in tcc. -Wall
does not alert you to the implicit int typing, sadly.