dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

questions to libs having a .h file and a .c file

Sat Sep 26, 2020 11:12 am

hi
another questions to libs having a .h file and a .c file:

normally I observe things like this (please CMIIW):

Code: Select all

//mylib.h
#pragma once

extern void myfunction();

Code: Select all

//mylib.c
#include "mylib.h"

void myfunction() {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.h"

int main() {
   myfunction();
   return 0;
}
1st question:
in which lib file (.h or .c) do I have to #include <stdio.h> ? Would either way work?

User avatar
Paeryn
Posts: 3079
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 11:39 am

dsyleixa123 wrote:
Sat Sep 26, 2020 11:12 am
hi
another questions to libs having a .h file and a .c file:

normally I observe things like this (please CMIIW):

Code: Select all

//mylib.h
#pragma once

extern void myfunction();

Code: Select all

//mylib.c
#include "mylib.h"

void myfunction() {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.h"

int main() {
   myfunction();
   return 0;
}
1st question:
in which lib file (.h or .c) do I have to #include <stdio.h> ? Would either way work?
In that example it's only needed in mylib.c since neither mylib.h nor mymainprogram.c rely on anything declared or defined in stdio.h.
mylib.c requires it as it contains a call to printf() so the header file needs to be included to provide the declaration.

Also, don't declare functions without parameters in C, it doesn't do what you think it does. If a function takes no parameters then declare it as taking void. Omitting parameters in the declaration says "I don't know how many parameters this function takes yet". C++ made it so that no parameters actually meant no parameters but C needed to stay compatible with old code so made the special case of taking void as being no parameters.

Code: Select all

extern void myfunction(void);

void myfunction(void) {
   printf("hello world");
}

int main(void) {
   myfunction();
   return 0;
}
Last edited by Paeryn on Sat Sep 26, 2020 11:48 am, edited 1 time in total.
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5900
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 11:41 am

FWIW, this is what I usually do - partial extracts (I also build with GNU Autotools):
Header file with defines & primitives:

Code: Select all

/* Header file associated with a SELection of PARsing functions etc.
 * $Id: parsel.h,v 1.1 2019/02/05 23:06:29 pi Exp $
 */

/* Conditionally Flag this file */
#ifndef PARSEL_H
#define PARSEL_H 1

#ifdef NO_MAIN
#define TRUE       1
#define FALSE      0
#define NUL        '\0'
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif /* NO_MAIN */

#include <time.h>
#include <unistd.h>

/* These #defines can be overidden by entries in the main source
 * file PRIOR to the #include of this file.
 */

#ifndef BLK_LEN
#define BLK_LEN          83  /* 80 + CR, LF & NUL */
#endif /* BLK_LEN */
#ifndef BUF_LEN
#define BUF_LEN         256
#endif /* BUF_LEN */
#ifndef FN_LEN
#define FN_LEN           64
#endif /* FN_LEN */
#ifndef CMD_LEN
#define CMD_LEN         138  /* 2 x FN_LEN + 10   */
#endif /* CMD_LEN */

#define NOT_PARSED -1
...
(File continues with a similar technique to handle globals )

Associated (library) source:

Code: Select all

/* C source file associated with a SELection of PARsing functions etc.
 * $Id: parsel.c,v 1.1 2019/02/05 23:06:29 pi Exp $
 */

#define NO_MAIN
#include "parsel.h"

/* Useful strings ... */
char blank[] = " ";
char error[] = "***ERROR*** ";
char warng[] = "**WARNING** "; 
/* Command Line Arguments and *.arg files ... */
char argfile[FN_LEN];
char argfopen=FALSE;
char argfread=FALSE;
FILE *afn;

void reset_stats(void)
{
  notab = TRUE;
  chars = 0;
  lines = 0;
}

void report_stats(char *file)
{
  if (!notab) printf("%s %s contained at least one tab character!\n",
		     warng,
		     file);
  printf("Processed %d characters in %d lines from %s.\n", 
	 chars, 
	 lines,
	 file);
}
...
More code follows defining various useful subroutines.

Trev.
Still running Raspbian Jessie or Stretch on some older Pi's (an A, B1, 2xB2, B+, P2B, 3xP0, P0W, 2xP3A+, P3B+, P3B, B+, and a A+) but Buster on the P4B's. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 11:53 am

ok, thank you!
same files, improved:

Code: Select all

//mylib.h
#pragma once

extern void myfunction(void);

Code: Select all

//mylib.c
#include <stdio.h>   
#include "mylib.h"

void myfunction(void) {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.h"

int main() {
   myfunction();
   return 0;
}
2nd question:
in mymainprogram.c I just #include "mylib.h"
I assume that the compiler then searches automatically for a file named mylib.c, although I didn't have to specify this mylib.c file anywhere, is that true?

User avatar
Paeryn
Posts: 3079
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 12:34 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 11:53 am
2nd question:
in mymainprogram.c I just #include "mylib.h"
I assume that the compiler then searches automatically for a file named mylib.c, although I didn't have to specify this mylib.c file anywhere, is that true?
No, the compiler doesn't care about mylib.c when it is compiling mymainprogram.c, it couldn't care less if the functions declared in mylib.h were actually compiled from Fortran, Pascal or any other language. The compilation of one source file is totally separate from the compilation of any other source file.

You do have to tell the linker the names of all the object files and libraries used when creating the final exectutable.
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 1:45 pm

hmmm - but how does the compiler know then, where the function

Code: Select all

//mylib.h
#pragma once

extern void myfunction(void);
can be found then, explicitely?
(tbh, I admit that I am Aduino-spoiled ;) )

User avatar
DougieLawson
Posts: 40170
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 1:57 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 1:45 pm

(tbh, I admit that I am Aduino-spoiled ;) )
That means you've been using C++ for all the time you've been coding on an Arduino.
Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All fake doctors are on my foes list.

Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 2:05 pm

not compellingly C++ code, also ISO C-style libs, but all and everything automatically compiled, linked, and built by Wiring and g++, yes.
Nonetheless, this don't answer my question:
dsyleixa123 wrote:
Sat Sep 26, 2020 1:45 pm
No, the compiler doesn't care about mylib.c when it is compiling mymainprogram.c, it couldn't care less if the functions declared in mylib.h were actually compiled from Fortran, Pascal or any other language. The compilation of one source file is totally separate from the compilation of any other source file.

You do have to tell the linker the names of all the object files and libraries used when creating the final exectutable.
hmmm - but how does the compiler know then, where the function

Code: Select all

//mylib.h
#pragma once

extern void myfunction(void);
can be found then, explicitely?

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5900
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 2:31 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 2:05 pm
not compellingly C++ code, also ISO C-style libs, but all and everything automatically compiled, linked, and built by Wiring and g++, yes.
Nonetheless, this don't answer my question:
dsyleixa123 wrote:
Sat Sep 26, 2020 1:45 pm
hmmm - but how does the compiler know then, where the function

Code: Select all

//mylib.h
#pragma once

extern void myfunction(void);
can be found then, explicitely?
The compiler doesn't need to know. In very simplified terms it reserves space for the linker to fill in with the required information.extern implies code etc. that has previously been compiled externally from the current compile process (and, of course,during that compilation the compiler did know where to find the source and where to put the compiled result for the linker to find.)
Trev.
Still running Raspbian Jessie or Stretch on some older Pi's (an A, B1, 2xB2, B+, P2B, 3xP0, P0W, 2xP3A+, P3B+, P3B, B+, and a A+) but Buster on the P4B's. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 2:55 pm

well, it gets more and more complicated...
in this case that means, that mylib.h and mylib.c have no meaningful dependence by names of each other, right?

so, question (3),
Both the .h file and the .c file also can be called by different names, e.g. mylib.h and foo.c, with the same effects and features, is that correct?

and question (3a), how would the command line compile/build parameters then look like?
dsyleixa123 wrote:
Sat Sep 26, 2020 11:53 am

Code: Select all

//mylib.h
#pragma once

extern void myfunction(void);

Code: Select all

//foo.c
#include <stdio.h>   
#include "mylib.h"

void myfunction(void) {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.h"

int main() {
   myfunction();
   return 0;
}

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5900
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 3:20 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 2:55 pm
well, it gets more and more complicated...
in this case that means, that mylib.h and mylib.c have no meaningful dependence by names of each other, right?

so, question (3),
Both the .h file and the .c file also can be called by different names, e.g. mylib.h and foo.c, with the same effects and features, is that correct?

...
Well you might be able to do that but you would have to remember the filenames etc.!. It could be considered "bad practice" and, AFAIK, most "automated" code building "environments" (GNU autotools, cmake, IDE's) tend to "expect" the ".h" and ".c" files to have the same prefix. (The resulting library name might be "more complex"). To give you some idea of what's involved for building codes dependent on multiple sources ie. the main code and that associated with (static) libraries see here: https://www.cpmspectrepi.uk/raspberry_p ... _files_etc.
(An IDE, whatever it's internal build process is, tends to hide that sort of detail of the mechanisms involved.)
Trev.
Still running Raspbian Jessie or Stretch on some older Pi's (an A, B1, 2xB2, B+, P2B, 3xP0, P0W, 2xP3A+, P3B+, P3B, B+, and a A+) but Buster on the P4B's. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
Paeryn
Posts: 3079
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 3:21 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 2:55 pm
well, it gets more and more complicated...
in this case that means, that mylib.h and mylib.c have no meaningful dependence by names of each other, right?

so, question (3),
Both the .h file and the .c file also can be called by different names, e.g. mylib.h and foo.c, with the same effects and features, is that correct?

and question (3a), how would the command line compile/build parameters then look like?
dsyleixa123 wrote:
Sat Sep 26, 2020 11:53 am

Code: Select all

//mylib.h
#pragma once

extern void myfunction(void);

Code: Select all

//foo.c
#include <stdio.h>   
#include "mylib.h"

void myfunction(void) {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.h"

int main() {
   myfunction();
   return 0;
}
Yes, there is nothing to say that a header file's name has any relevance to any similar named source file. The functions declared in a header file could be defined over multiple source files.

Compiling your two source files and creating an executable could be done like:

Code: Select all

$ gcc -c -o foo.o foo.c
$ gcc -c -o mymainprogram.o mymainprogram.c
$ gcc -o mymainprogram mymainprogram.o foo.o
The first line compiles foo.c into an object file foo.o
The second line compiles mymainprogram.c into an object file mymainprogram.o
The third line takes those two object files, links them together along with the C standard library and necessary startup code to produce your final executable.

Edit:
gcc will, if you omit the output filename option (-o filename.o) when compiling to object files, automatically name it with the same base name of the source but change the .c into .o, I just added it for completeness. If however you omit naming the executable then the resultant filename will be a.out

Though for a simple case like this you can just tell gcc to handle the object files transparently for you, in which case gcc will create temporary object files for each source file and delete them after it has linked them.

Code: Select all

$ gcc -o mymainprogram mymainprogram.c foo.c
Last edited by Paeryn on Sat Sep 26, 2020 3:33 pm, edited 1 time in total.
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 3:30 pm

(3b) as to

Code: Select all

$ gcc -o mymainprogram mymainprogram.c foo.c
where is the mylib.h file mentioned in my special case? e.g.,

Code: Select all

-Imylib.h
? Is there no need?

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5900
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 3:45 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 3:30 pm
(3b) as to

Code: Select all

$ gcc -o mymainprogram mymainprogram.c foo.c
where is the mylib.h file mentioned in my special case? e.g.,

Code: Select all

-Imylib.h
? Is there no need?
IIRC (as I rarely "do it all" on the command-line) the -I option is not for header (*.h) files (they're Included in the 'C' source (*c) files) but for (pre-compiled) object (*.o) files.
Trev.
Still running Raspbian Jessie or Stretch on some older Pi's (an A, B1, 2xB2, B+, P2B, 3xP0, P0W, 2xP3A+, P3B+, P3B, B+, and a A+) but Buster on the P4B's. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 3:52 pm

i.e., no cmd line parameter for the header file (mylib.h) at all?

(jtm, for qt5 using wiringPi and ads1115.c I had to add both

Code: Select all

 -lwiringPi
 -Iads1115.h
IIRC)

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5900
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 4:00 pm

Correction to my previous post - I didn't RC :oops: - partially because, for me, the "-I" options are generated automatically by the build process. FWIW below is an example for a fairly simple build**

Code: Select all

pi@raspiP4B4b-32GbP:~/pi_tools_etc/usdcard_tools-0.0 $ make
make  all-recursive
make[1]: Entering directory '/home/pi/pi_tools_etc/usdcard_tools-0.0'
Making all in common
make[2]: Entering directory '/home/pi/pi_tools_etc/usdcard_tools-0.0/common'
gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT parsel.o -MD -MP -MF .deps/parsel.Tpo -c -o parsel.o parsel.c
mv -f .deps/parsel.Tpo .deps/parsel.Po
rm -f libparsel.a
ar cru libparsel.a parsel.o 
ar: `u' modifier ignored since `D' is the default (see `U')
ranlib libparsel.a
make[2]: Leaving directory '/home/pi/pi_tools_etc/usdcard_tools-0.0/common'
Making all in src
make[2]: Entering directory '/home/pi/pi_tools_etc/usdcard_tools-0.0/src'
gcc -DHAVE_CONFIG_H -I. -I..  -I../common   -g -O2 -MT cid_decoder-cid_decoder.o -MD -MP -MF .deps/cid_decoder-cid_decoder.Tpo -c -o cid_decoder-cid_decoder.o `test -f 'cid_decoder.c' || echo './'`cid_decoder.c
In file included from cid_decoder.c:23:
../common/rcs_scm.h: In function ‘getRCSDate’:
../common/rcs_scm.h:107:17: warning: trigraph ??/ ignored, use -trigraphs to enable [-Wtrigraphs]
   strcpy(temp, "??/??/200?");
                  
../common/rcs_scm.h:107:20: warning: trigraph ??/ ignored, use -trigraphs to enable [-Wtrigraphs]
mv -f .deps/cid_decoder-cid_decoder.Tpo .deps/cid_decoder-cid_decoder.Po
gcc  -g -O2   -o cid_decoder cid_decoder-cid_decoder.o ../common/libparsel.a  
make[2]: Leaving directory '/home/pi/pi_tools_etc/usdcard_tools-0.0/src'
make[2]: Entering directory '/home/pi/pi_tools_etc/usdcard_tools-0.0'
make[2]: Leaving directory '/home/pi/pi_tools_etc/usdcard_tools-0.0'
make[1]: Leaving directory '/home/pi/pi_tools_etc/usdcard_tools-0.0'
Trev.
**of this toolset : https://www.cpmspectrepi.uk/raspberry_p ... cking.html
Still running Raspbian Jessie or Stretch on some older Pi's (an A, B1, 2xB2, B+, P2B, 3xP0, P0W, 2xP3A+, P3B+, P3B, B+, and a A+) but Buster on the P4B's. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 4:07 pm

I don't understand the asm-like statements, but back to my original question, what is the correct answer?
dsyleixa123 wrote:
Sat Sep 26, 2020 3:30 pm

Code: Select all

//mylib.h
#pragma once

extern void myfunction(void);

Code: Select all

//foo.c
#include <stdio.h>   
#include "mylib.h"

void myfunction(void) {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.h"

int main() {
   myfunction();
   return 0;
}
(3b) as to

Code: Select all

$ gcc -o mymainprogram mymainprogram.c foo.c
where is the mylib.h file mentioned in my special case? e.g.,

Code: Select all

-Imylib.h
? Is there no need?

User avatar
Paeryn
Posts: 3079
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 4:24 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 4:07 pm
I don't understand the asm-like statements, but back to my original question, what is the correct answer?
dsyleixa123 wrote:
Sat Sep 26, 2020 3:30 pm
(3b) as to

Code: Select all

$ gcc -o mymainprogram mymainprogram.c foo.c
where is the mylib.h file mentioned in my special case? e.g.,

Code: Select all

-Imylib.h
? Is there no need?
Your C source file names the headers (possibly with a partial path). The compiler (preprocessor) will search for the header files in various places, e.g. the directory that the source file is in and then various system directories including/usr/include. Note that when using angled brackets in a #include rather than quotes then the source directory isn't searched.

If you know the header files aren't in any of the standard search paths the you add -Ipathname (that is a capital I for Include, not to be confused with l for library, fonts can be awkward rendering the two very similar if not the same) to the compile line to add pathname to the search paths.
E.g. if your mylib.h header file was in the directory headers from the source directory (so it would be found in headers/mylib.h) then

Code: Select all

$ gcc -o mymainprogram -Iheaders mymainprogram.c foo.c
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 4:38 pm

ahaaa....
(4)
so IIUC, that is why in my .c library file (foo.c or whatever) there is the line required

Code: Select all

#include "mylib.h"
to link it automatically, without extra command line parameters?
or why is it needed here?

or is the .h file included because of the same line #include "mylib.h" in my mainprogram.c ?

User avatar
Paeryn
Posts: 3079
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 4:53 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 4:38 pm
ahaaa....
so IIUC, that is why in my .c library file (foo.c or whatever) there is the line required
#include "mylib.h"
?
This is the crucial line why my .h header file will be automatically linked in and need no additional linke parameters?
Header files aren't "linked" in, what happens is the preprocessor creates a temporary copy of your source file and replaces the #include "mylib.h" line with the contents of mylib.h along with any other preprocessor transforms. It is this temporary file which is actually compiled.

Note: a temporary file might not be actually created as the preprocessor is built in to gcc's c compiler rather than run as a separate process, but conceptually it is.
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 5:09 pm

(5)
hmmm, if the header file mylib.h is actually not linked, why is it needed anyway?
Couldn't I simply drop it and just use the former .c file mylib.c?
and include it in my mainproram via

Code: Select all

// mylib.c
void myfunction(void) {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.c"

int main() {
   myfunction();
   return 0;
}
Last edited by dsyleixa123 on Sat Sep 26, 2020 5:15 pm, edited 3 times in total.

Heater
Posts: 16832
Joined: Tue Jul 17, 2012 3:02 pm

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 5:11 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 4:38 pm
to link it automatically, without extra command line parameters?
or why is it needed here?

or is the .h file included because of the same line #include "mylib.h" in my mainprogram.c ?
No.

Imagine you have a C file with your main() in it. Call it "main.c".
You also have another file with a bunch of functions in it that you want to call from main.c. Let's call that "funcs.c"

Now, when you compile main.c it fails. Because it knows nothing about any of those functions out there somewhere that it wants to call.

So we introduce a header file, call it "funcs.h". In there we put declarations for all the functions in funcs.c.
And we add '#include "funcs.h"' to the top of main.c.

Now we can compile main.c into an object file because it knows all about the functions it want to call. Their names, their parameters and parameter types, their return values and types. Note that at this stage it does not mater where funcs.c is. Or even it if it exists at all!

With all the above we can now compile main.c in to an object file main.o. But we don't have a complete executable yet. We need to compile funcs.c as well and link the resulting object files, main.o and func.o into an executable program.

How does the compiler know where funcs.h is when it compiles main.c? Well, it will look in the current directory. It will also look in any directory specified on the command line with the -I option: https://www.rapidtables.com/code/linux/gcc/gcc-i.html

In short. A program is built by compiling a bunch of .c source files into a bunch of .o object files.
They can all be compiled totally independently because the various .h header files tell them about what is out there that they are using.
Then the complete executable is built by linking all those .o object files together.

Header files do not magically tell the compiler where the actual C source files that implement any particular header files declarations are.
Memory in C++ is a leaky abstraction .

dsyleixa123
Posts: 1025
Joined: Mon Jun 11, 2018 11:22 am

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 5:18 pm

thanks, Heater, I think I understand your point.
now there was intermediately perhaps a crossover-posting.
what about this question (5)?
dsyleixa123 wrote:
Sat Sep 26, 2020 5:09 pm
(5)
hmmm, if the header file mylib.h is actually not linked, why is it needed anyway?
Couldn't I simply drop it and just use the former .c file mylib.c?
and include it in my mainproram via

Code: Select all

// mylib.c
void myfunction(void) {
   printf("hello world");
}

Code: Select all

//mymainprogram.c
#include "mylib.c"

int main() {
   myfunction();
   return 0;
}

Heater
Posts: 16832
Joined: Tue Jul 17, 2012 3:02 pm

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 5:29 pm

dsyleixa123 wrote:
Sat Sep 26, 2020 5:09 pm
hmmm, if the header file mylib.h is actually not linked, why is it needed anyway?
Couldn't I simply drop it and just use the former .c file mylib.c?
and include it in my mainproram via
You could. But then in a big program that might have hundreds of C files you could end up including the same C source of some other C file in hundreds of files. You end up recompiling the the same code over and over again.

Arguably you could just include C source, which includes other C source, which includes other C source... and build the whole program in one step. Even with our modern machines with lot's of memory that is likely to fail for lack of memory for big programs. Besides taking a very long time.

Actually I think that logically header files are not necessary. They exist mostly because when C was invented computers were very much slower and had very little memory. So one had to arrange that small parts of a big program could be compiled separately so that it could be done in the space available. Then those small compiled parts, the object files, get linked into the complete program. Header files were required so that when one small part, a C source file, was being compiled it knew what was available in those other small parts that it could not see.

Did you know that the first C compiler ran on on a PDP 11 (9 maybe?) with only 4K of RAM. That's kilobytes!

If you look at a modern language like Rust it does not have header files. You just have code in modules and the build system finds what it needs.

Of course even with hour massive memories and speed of machines today slow build times are something that people complain about in Rust.
Last edited by Heater on Sat Sep 26, 2020 5:38 pm, edited 1 time in total.
Memory in C++ is a leaky abstraction .

Heater
Posts: 16832
Joined: Tue Jul 17, 2012 3:02 pm

Re: questions to libs having a .h file and a .c file

Sat Sep 26, 2020 5:37 pm

Also, consider the case of libraries for which you have binary library files. Shared objects, .so, or statically linked library files, .a.

If your program wants to use those it needs to know what functions and other stuff they offer. But it does not have access to the source files of those libraries. The library header files tell what is in the library and ensure your compilation is correct.

And anyway, you don't want to be compiling those libraries by including their source. Last time I built QT 5 on a Pi it took all night!

No, we just build our programs against the library header files. Then link the library objects.
Memory in C++ is a leaky abstraction .

Return to “C/C++”