stdio.h

This is a discussion on stdio.h within the C Programming forums, part of the General Programming Boards category; I am a newb to c programming and I just finished my first book on the basics on c programming. ...

stdio.h

I am a newb to c programming and I just finished my first book on the basics on c programming. But I am still curious about the functions that are in stdio.h among other headers, where are the functions actually defined at? I hope I am using the correct terms here. So correct me if I'm wrong when I say they are prototyped in the stdio.h but not defined there.

They live in a library that is linked against when you compile.
If you use the gcc compiler, and a lot of others, the standard functions live in a library called libc. This is the standard C library. The extension on the libc library file is different for different operating systems.

On Unix boxes it is usually one of: libc.so, libc.sl, libc.a
Where these files live is implementation dependent

<...> I am still curious about the functions that are in stdio.h among other headers, where are the functions actually defined at?

It's a good question. So many newbies are not curious enough about that, and this point is actually almost never seriously treated in books. You desserve an explanation.

I hope I am using the correct terms here. So correct me if I'm wrong when I say they are prototyped in the stdio.h but not defined there.

That's correct enough to me.

The idea is that the C-language allows separated compiling. It means that a project (say, big, but not necessarely) can (shall) be divided into smaller parts called compile units[1]. These CU can then be linked by a dedicated tool called a linker.

The result is the executable file.

Each compile unit must have at last one reference with external linkage. (Often a function, rarely an object)

Say :

Code:

/* a.c */
void a_init(void)
{
}

Any C application must have a main() entry function. Say that it calls a_init():

Code:

/* main.c */
int main (void)
{
a_init();
return 0;
}

If I try to compile this code, I will probably have a warning about 'missing prototype' or the like.

The naive fix : add a function declaration:

Code:

/* main.c */
a_init ();
int main (void)
{
a_init();
return 0;
}

The compiler is still complaining about missing prototypes. Sure, we supplied a declaration instead of a prototype. Let's try with the prototype:

Code:

/* main.c */
a_init (void);
int main (void)
{
a_init();
return 0;
}

Sounds good, but it's not safe. The function is supposed to return nothing, and the prototype claims that it returns an int (implicit). We are allowed to write such a code :

But the value in ret will never be determined. The behaviour is undefined.

The Good Way is to define a 'common' file known as 'headers file' (aka 'header') that contains the headers of the function in prototype forms (aka 'prototypes') and all required definitions and declarations. It is highly recommended that the file is both included into the definition file and the user files.

Code:

/* a.h */
#ifndef H_A
#define H_A
void a_init(void);
#endif /* H_A */

Note that the #ifndef stuff is a protection against multiple inclusions.

This will not compile, because the use of the function doesn't match the prototype. I let you make the fix.

To answer your initial question, the definitions of the functions declared in the standard headers are probably stuck in some 'library' (collection of compiled functions). The details belong to your implementation, and, in most cases, you should not care about it.

HTH

---------------------
[1] On what criteria are they devided is the result of the design process (state #2 of the project life chart)