[SOLVED] Confusion about C header files and object files.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm a little confused about this, and I can't find a good explanation of it anywhere.
When is it good to use separate translation units and object files and link them into the main C program, and when is it good to include the header files in the main C program? I don't understand if most people include header files or if most people just link in object files and use their contents in the main program. It's sort of a simple question, but it's confusing to me and that's why I need help with it. I sort of don't understand the difference, or if there's really no difference other than the way the final result is achieved, which way is better or preferred, etc...
For example:
Code:
main.c:
#include "part_of_my_program.h"
/* things from part_of_my_program.c */
or:
Code:
main.c:
/* things from part_of_my_program.c */
cc -o my_program main.o part_of_my_program.o
Can anyone help me with a simple explanation of the difference, or which one is preferred or better, or something to help my confusion?
I've read a little on the ELF format... so is there no difference in the end result? It's just a matter of preference or necessity, and where the information is to begin with?
Last edited by pr_deltoid; 09-18-2010 at 01:23 PM.
Click here to see the post LQ members have rated as the most helpful post in this thread.
It seems to me like the end result would be the same, and it would just be a matter of preference or necessity, or maybe specific situations where it would be a better idea to just link in an object file. Everything ends up the same in the final ELF file, so it's probably more common to include the header files, huh?
Or is it common to just make a bunch of separate object files and link them together with the main object file, that includes the main() function?
Any kind of help clearing this up would be appreciated.
Last edited by pr_deltoid; 09-18-2010 at 01:16 PM.
The general mixing of header files and object files and linking is confusing to me.
What's necessary? Do people mix the inclusion of header files and the linking of object files? Can anyone point me to a good tutorial on this?
I thought I understood this process, and I just realized that I have no idea what's happening and why things are done the way they are, when I think of the overall header files, object files, and linking being mixed together like they are.
If you can do without the inclusion of a header file, if you just link in the object file of the .c file that you're including things from, what difference does the inclusion of the header file make?
Last edited by pr_deltoid; 09-18-2010 at 01:22 PM.
First you need to understand the difference between declaring and defining in C.
Good programming of large projects in C usually involves declaring functions in .h files and defining them in .c files.
You can call functions in C without first declaring them, but it is not a good practice. So any .c file that includes calls to a function should #include the .h file that declares the function.
Do you know a simple explanation of whether there is any difference in the final ELF executable depending on whether you include the header file of the .c file that ends up being a linked-in .o object file or you just link in the .o object file?
[prdeltoid@home /usr/home/prdeltoid/C]$ gcc -Wall -o test main.c testhello.c
main.c: In function 'main':
main.c:3: warning: implicit declaration of function 'testhello'
[prdeltoid@home /usr/home/prdeltoid/C]$ ./test
hello
What's the difference? Is the ELF file any different? Why bother with the inclusion of testhello.h in main.c if nothing changes except the implicit declaration warning? Do people usually include testhello.h just to add clarity and to avoid the warning?
Last edited by pr_deltoid; 09-18-2010 at 02:19 PM.
Do you know a simple explanation of whether there is any difference in the final ELF executable depending on whether you include the header file of the .c file that ends up being a linked-in .o object file or you just link in the .o object file?
If you are talking about ordinary headers (declaring functions, etc.) and about ordinary .o files (defining those functions) then the question you are asking is almost the same as asking the pitfalls of calling undeclared functions in C.
If you call an undeclared function in C, the compiler will make assumptions about the parameter types and return type of the function. Those assumptions may not be correct, in which case the compiled function would not be correct, in which case the difference in the final ELF executable is correct vs. incorrect.
A header might also declare struc's, enum's typedef's, etc. that other .c models need. Then failing to include the header will cause an error at compile time.
I didn't know that non-function declarations or definitions wouldn't work. I just tried what I posted before with an enum and a typedef and received compiler errors. Do you know a simple explanation for why an object file with nothing but includes and functions will work the way I posted above, but typedef, enum, etc. won't?
It's the ELF format and the way the linking works, right?
Thanks very much for your help, and now that I've thought about it for a while and learned that things other than functions don't work that way, I have a much better understanding.
Last edited by pr_deltoid; 09-18-2010 at 02:38 PM.
I'm no expert, so everyone feel free to correct me where I'm wrong.
You can include a lot of things in an include file, but I think your question really is about the C function prototypes. The function prototypes merely tell the compiler what, if anything, gets passed on the stack to a called function; and what, if anything, gets returned on the stack from a called function.
The prototypes produce no code. They are just there to make sure that a function is called properly.
As johnsfine said, prototypes are optional. With the pre-ANSI C compiler prototypes were optional. But the coder really needed to keep track of all of that stuff. If you coded a call to a function and passed two int variables on the stack, and the function expected three and popped three off the stack, a painful debugging session would follow... With ANSI C compilers there is a flag you have to specify so that strict prototyping is not done.
It doesn't matter if the function is coded in the main C program, or external to it and linked into the elf executable later (except maybe the order of the code segments). But functionally they have the same content.
The readelf and objdump commands can show you information about your executables. ('man elf' will give you the gory details of an elf binary.)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.