1

Couldn't stdio functions and variables be defined in header files without having to use .c files.

If not, what are .c files used for?

4 Answers4

7

The functions defined in the header file have to be implemented. The .c file contains the implementation, though these have already been compiled into a static or shared library that your compiler can use.

The header file should contain a minimal description of the function to save time when compiling. If it included the entire source it'd force the compiler to rebuild it each and every time you compile which is really wasteful since that source never changes.

In effect, the header file serves as a cheat sheet on how to interact with the already compiled library.

The reason the .c files are provided is primarily for debugging, so your debugger can step through in your debug build and show you source instead of raw machine code. In rare cases you may want to look at the implementation of a particular function in order to better understand it, or in even more rare cases, identify a bug. They're not actually used to compile your program.

In your code you should only ever reference the header file version, the .h via an #include directive.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 1
    If the functions and variables exist in the .c file, why use a .h file in the first place? – cprogrammer100 Aug 07 '19 at 23:49
  • 6
    C was created decades ago, when computer time was expensive. Many of its rules, like having to declare a function before it is used, are designed to make the compilation process faster. Modern languages don't generally have these restrictions, because the programmer doesn't much care if code compiles in 100 milliseconds or 300 milliseconds. But back in the 70s, 1 minute or 3 minutes was a bigger deal. – Lee Daniel Crocker Aug 08 '19 at 00:05
  • 1
    A `.h` file allows the compiler to quickly understand how to use the code without having to compile it. This saves enormous amounts of time when assembling the final executable. If you had to recompile everything, every time, even the tiniest of changes to your code would require building the whole universe from the ground up. – tadman Aug 08 '19 at 00:21
3

stdio.h is a standard header, required to be provided by every conforming hosted C implementation. It declares, but does not define, a number of entities, mostly library functions like putchar and scanf.

stdio.c, if it exists, is likely to be a C source file that defines the functions declared in stdio.h. There is no requirement that an implementation must make it available. It might not even exist; for example the implementations of the functions declared in stdio.h might appear in multiple *.c files.

The declaration of putchar is:

int putchar(int c);

and that's all the compiler needs to know when it sees a call to putchar in your program. The code that implements putchar is typically provided as machine code, and the linker's job is to resolve your putchar() call so it ends up invoking that code. putchar() might not even be written in C (though it probably is).

An executable program can be built from multiple *.c source files. One and only one copy of the code that implements putchar is needed for an entire program. If the implementation of putchar were in the header file, then it would be included in each separately compiled source file, creating conflicts and, at best, wasting space. The code that implements putchar() (and all the other functions in the library) only needs to be compiled once.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
1

The .c files has specific function for any aim. For example stdio.c files has standart input-output functions to use within C program. In stdio.h header files has function prototypes for all stdio.c functions, all defines, all macros etc. When you #include <stdio.h> in your main code.c file your main code assumes there is a " int printf(const char *format, ...)" function. Returns int value and you can pass argument ..... etc. When you call printf() function actually you use stdio.c files..

Mike
  • 4,041
  • 6
  • 20
  • 37
embeddedpc
  • 11
  • 1
0

There are languages where if you want to make use of something someone else has written, you say something like

import module

and that takes care of everything.

C is not one of those languages.

You could put "library" source code in a file, and then use #include to pull it in wherever you needed it. But this wouldn't work at all, for two reasons:

  1. If you used #include to pull it in from two different source files, and then linked the two resulting object files together, everything in the "library" would be defined twice.

  2. You might not want to deliver your "library" code as source; you might prefer to deliver it in compiled, object form.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Would it be correct to say that C uses header files to declare functions and variables that will/may be used and the .c files which define them. – cprogrammer100 Aug 08 '19 at 00:04
  • 1
    Turbo Pascal is one of the best examples of this with modules being a first-class feature of that language and the compilation times are positively *stupid* fast. C isn't anywhere near, but it is a lot faster once running, so that's why people use C and not Pascal. The good news is C++ is eventually going to get modules, so maybe compilation times will improve a bunch accordingly. – tadman Aug 08 '19 at 00:22
  • @tadman: There was [a lot more to Turbo Pascal compilation speed](https://prog21.dadgum.com/47.html) than mere "modules as language feature". Of the points mentioned there, C/C++ compilers aren't moving to an integrated build system, and the linker is getting more complicated, not less (to enable link time optimization to maximize speed while removing redundant/unused code). Modules may help, but modules alone aren't going to get you to Turbo Pascal compilation speeds (and that's a good thing, since much of Turbo Pascal's compilation speed came from foregoing optimization). – ShadowRanger Aug 08 '19 at 00:47