Expected behaviour is that your functions will get called, provided the object files are linked together. Any undeclared function, is assumed to be an external function that returns an integer for compile purpose, and an external symbol (to the object file) for purposes of linking. I'll give you concrete example:
foo.c:
void foo(const char *name) {
printf("foo called with %s\n", name);
}
bar.c:
void bar(int a) {
printf("bar called with %d\n", a);
}
main.c:
int main(int argc, char *argv[]) {
foo("Hello");
bar(5);
return 0;
}
Compiling the object files using gcc:
gcc -fno-builtin -ansi -c -o foo.o foo.c
gcc -fno-builtin -ansi -c -o bar.o bar.c
gcc -fno-builtin -ansi -c -o main.o main.c
These should not produce any warnings or errors
Now link them together:
gcc -o progy main.o bar.o foo.o
Note that i used gcc to link the binaries, but that is equivalent of:
ld -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o progy /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbegin.o main.o foo.o bar.o -lc -L/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1 -lgcc -lgcc_s /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtend.o /usr/lib64/crtn.o
on my Linux 64-bit platform. (GCC actually runs LD like this to do the linking)
Using your C compiler (in my case gcc) for linking will ensure that linker is called correctly for whatever your build target platform is. If you use an IDE then these steps are all hidden by a nice interface.