In C, it is not an error to cast a pointer from one type to another. However, a good compiler will generate a warning when passing the wrong pointer type to a function without an explicit cast. If you're not getting a warning, I strongly recommend checking your compiler settings to make sure warnings are turned on. Or consider using a different compiler. ;-)
To understand why it works, you need to understand a bit about assembly language and how C uses the stack to pass parameters. You can visualize the stack as a big stack of plates, where each plate holds one simple variable. On many platforms, all parameters are passed on the stack. func
will push y
and x
, call f
, then pop the variables back off. valid
loads x
and y
by looking at the two top entries on the stack. invalid
finds x
by looking at the top entry on the stack.
Here's what the stack might look like inside invalid:
main: 3
uninitialized
f: 2
1
invalid
invalid: 2
1
invalid()
takes one parameter, so it just looks at the top of the stack (the 1) and loads it as the parameter.
This is also how functions like printf
work. They can accept a variable number of parameters. The first parameter is at the top of the stack, and they can just keep looking down the stack for however many parameters they need. Some systems pass some parameters in registers instead of using the stack, but it works analogously.
In the very early days of C, function declarations did not include parameters at all. In fact, if you declare a function without anything between the parenthesis, you can still define a function that way. For example, this compiles just fine:
void foo();
void bar(void) {
foo(5); /* foo's parameters are implicit */
}
That's why it's important to include the void
when declaring a function without parameters. It tells the compiler that the function really takes no parameters. With nothing between the parentheses, it's a function with implicit parameters.