In general, if you called a function not defined anywhere, you will see error by linker, not compiler. Compiler may give you warning for implicit declaration but usually let it go.
An example, using gcc 8.3 to compile your file1.c:
$ gcc -o test file1.c
file1.c: In function ‘main’:
file1.c:5:5: warning: implicit declaration of function ‘printNumber’ [-Wimplicit-function-declaration]
printNumber(2);
^~~~~~~~~~~
/usr/bin/ld: /tmp/ccs0wv7L.o: in function `main':
file1.c:(.text+0xf): undefined reference to `printNumber'
collect2: error: ld returned 1 exit status
Note the warning is from compiler but only the ld
(linker) give you error for undefined reference to the function.
So I suspect you compile the program like the following, which the linker is smart enough to relate the object codes:
$ gcc -o test file1.c file2.c
file1.c: In function ‘main’:
file1.c:5:5: warning: implicit declaration of function ‘printNumber’ [-Wimplicit-function-declaration]
printNumber(2);
^~~~~~~~~~~
file2.c: In function ‘printNumber’:
file2.c:3:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
printf("Number %d is printed.", number);
^~~~~~
file2.c:3:5: warning: incompatible implicit declaration of built-in function ‘printf’
file2.c:3:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
file2.c:1:1:
+#include <stdio.h>
void printNumber(int number)
file2.c:3:5:
printf("Number %d is printed.", number);
^~~~~~
You see warnings above but it actually compiles and the linker does not complain. If you run this in your IDE, probably you don't even see the warning messages. So you have the illusion that your code works even you think it should have an error