Author Topic: [C] do i need a *.h file for every *.c file?  (Read 2934 times)

0 Members and 1 Guest are viewing this topic.

Offline Simon

  • Global Moderator
  • *****
  • Posts: 13948
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
[C] do i need a *.h file for every *.c file?
« on: January 21, 2019, 09:51:27 am »
New project new questions.

So obviously I will split my project into several c files but do I really need a header file for each? If i list the various function prototypes in main.h will that suffice?

I'd also like to put all variables (they are mostly all external) into a separate c file, again is this OK ? or is a header file best?

In the past I had tried to have my own "library files" but i have abandoned that idea in favour of writing my own instruction manual with gotcha's and all for each module and usage case of the micro controller used so that i just run through those instructions and set up the peripheral from scratch in each program so no file will necessarily be reusable in another project.
https://www.simonselectronics.co.uk/shop
Varied stock of test instruments and components including EEVblog gear and Wurth Elektronik Books.
Also, if you want to get ripped off: https://www.ebay.co.uk/usr/simons_electronics?_trksid=p2047675.l2559
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 3333
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: [C] do i need a *.h file for every *.c file?
« Reply #1 on: January 21, 2019, 09:55:09 am »
No. But you might want to manage dependencies, and which modules recompile when changing something.
With one header file, all C files recompile.
 

Online Rerouter

  • Super Contributor
  • ***
  • Posts: 4402
  • Country: au
  • Question Everything... Except This Statement
Re: [C] do i need a *.h file for every *.c file?
« Reply #2 on: January 21, 2019, 09:56:19 am »
If its for yourself, the sky is green and the ocean is orange, anything goes as long as it does what you need it to, and when you come back to it you can pick it up without requiring twilight madness/clarity for it to make sense.

If your making code for a job or others, probably find a style guide and refer to that.  e.g. https://google.github.io/styleguide/cppguide.html
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 13948
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [C] do i need a *.h file for every *.c file?
« Reply #3 on: January 21, 2019, 10:00:51 am »
Well i am trying to make it simpler to go back to. With every additional file actually being 2 additional files the complexity goes up fast. Ultimately it is a program that will be split into separate c files for ease of managing and clarity. most variables will be global anyway.

Do i assume correctly that a variable declared outside of a function in any file will essentially be taken as declared globally before any of the c code runs? I guess i will find out soon ;)
https://www.simonselectronics.co.uk/shop
Varied stock of test instruments and components including EEVblog gear and Wurth Elektronik Books.
Also, if you want to get ripped off: https://www.ebay.co.uk/usr/simons_electronics?_trksid=p2047675.l2559
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 3333
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: [C] do i need a *.h file for every *.c file?
« Reply #4 on: January 21, 2019, 10:08:25 am »
Everything in one big file makes it more obfuscated.

Do i assume correctly that a variable declared outside of a function in any file will essentially be taken as declared globally before any of the c code runs? I guess i will find out soon ;)
Yes. But there is the static keyword to keep the variable within the file.
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9212
  • Country: my
  • reassessing directives...
Re: [C] do i need a *.h file for every *.c file?
« Reply #5 on: January 21, 2019, 10:34:19 am »
Well i am trying to make it simpler to go back to.
there are few reason why you need *.h file...
1) a place to declare function's prototypes for usage in the same c file.
2) to publish "public" functions/classes/types etc for usage from different c files (some call modules some call units)
3) to gather few *.h files in one single h file for easy structure call (include)
4) others may add...

if non of the above that you need, your c doesnt need h file.

there are few things *.h file is not for...
1) declaring (with definition) variables that will allocate space in memory. allocation/definition should be made in c file
2) class with template (undefined data type T)
3) others may add...

<give a man a fish he will feed for a day. teach a man how to fish he will feed for a lifetime>

If its for yourself, the sky is green and the ocean is orange, anything goes as long as it does what you need it to
this quote is good for stubborn man. but soon he will realize that green and orange will bite on his butt after a while if he doesnt get it right. there are reasons why experienced professionals laid out things in a way we thought unreasonable...
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 13948
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [C] do i need a *.h file for every *.c file?
« Reply #6 on: January 21, 2019, 10:44:37 am »
I am just trying to avoid doubling my files and making it as unmanageable as having one file.
https://www.simonselectronics.co.uk/shop
Varied stock of test instruments and components including EEVblog gear and Wurth Elektronik Books.
Also, if you want to get ripped off: https://www.ebay.co.uk/usr/simons_electronics?_trksid=p2047675.l2559
 

Offline CJay

  • Super Contributor
  • ***
  • Posts: 3424
  • Country: gb
  • M0UAW
Re: [C] do i need a *.h file for every *.c file?
« Reply #7 on: January 21, 2019, 11:27:46 am »
New project new questions.

So obviously I will split my project into several c files but do I really need a header file for each? If i list the various function prototypes in main.h will that suffice?

I'd also like to put all variables (they are mostly all external) into a separate c file, again is this OK ? or is a header file best?

In the past I had tried to have my own "library files" but i have abandoned that idea in favour of writing my own instruction manual with gotcha's and all for each module and usage case of the micro controller used so that i just run through those instructions and set up the peripheral from scratch in each program so no file will necessarily be reusable in another project.

As a 'tinkerer' programmer, if I write a module to control, say, a DDS chip or RTC then I create a .h to go with it.
To my mind, it makes it easier to re-use the code, I'm sure other people will disagree but it works for me and that's what's important. 
M0UAW
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 13948
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [C] do i need a *.h file for every *.c file?
« Reply #8 on: January 21, 2019, 11:33:10 am »
a function produces a value of a tacho signal frequency, that tacho value is used by a speed setting function to correct a speed. tacho is therefor a global variable as two functions have access to it.

the program runs on a timer that carries out the main function every "x" time and that value is used by multiple functions, it is therefore a global variable.

buttons will be pressed and every time a button is scanned by the button read function the "button pressed" variable will be updated and then looked at again when that function runs again so "button pressed" is a global variable or it's value will be lost at the end of the button scan function.

Considering it is not a massive program and that most variables need accessing by consecutive instances of the same function without values being lost or variables are used by multiple functions all variables will end up being globals and this also makes me disciplined in naming variables
https://www.simonselectronics.co.uk/shop
Varied stock of test instruments and components including EEVblog gear and Wurth Elektronik Books.
Also, if you want to get ripped off: https://www.ebay.co.uk/usr/simons_electronics?_trksid=p2047675.l2559
 

Offline taydin

  • Frequent Contributor
  • **
  • Posts: 461
  • Country: tr
Re: [C] do i need a *.h file for every *.c file?
« Reply #9 on: January 21, 2019, 11:39:42 am »
There are two main purposes for header files:

1) Defining global values that are used throughout the project. For example, a network port address, maximum minimum values for certain settings, structures, type definitions that are used througout the system. Header files avoid duplication by allowing you to just include the header file and use the contents whereever you want. And when you change one of the definitions or values in the header file, it is reflected throughout the entire project. This is a very powerful tool to avoid duplication.

2) Making the functionality implemented in a C/C++ module available to other modules. You add all functions, structures, typedefs and defines in the module that are for public use into the header file, and then whoever wants to utilize the capabilities in the module just include the header file.

There are other advantages and valid use cases as well, but the above are the ones that have the most impact.
Real programmers use machine code!

My hobby projects http://mekatronik.org/forum
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 12051
  • Country: gb
    • Mike's Electric Stuff
Re: [C] do i need a *.h file for every *.c file?
« Reply #10 on: January 21, 2019, 12:10:33 pm »
Another approach is to have a .h file for different logical categories of information, e.g. one for hardware port definitions, one for global constants, one for compile-time configurations, one for protocol-related parameters, and each C file includes only whichever ones are relevant to it. 
I think that can make more logical sense than a .h for each .c file - I don't really see much point in the latter approach. 
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 6541
Re: [C] do i need a *.h file for every *.c file?
« Reply #11 on: January 21, 2019, 12:46:18 pm »
It doesn't matter to the compiler so there is really no right answer ---  do whatever feels right and most convenient to you.

 

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • Posts: 2133
  • Country: tr
Re: [C] do i need a *.h file for every *.c file?
« Reply #12 on: January 21, 2019, 12:56:09 pm »
Keep in mind that you can include a .c into a .c simply #include "pwm.c" or #include "globals.c" or #include "buttonscode.c" etc. do that wisely and you'll need no .h headers nowhere.
git diff *
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 13948
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [C] do i need a *.h file for every *.c file?
« Reply #13 on: January 21, 2019, 01:08:38 pm »
Keep in mind that you can include a .c into a .c simply #include "pwm.c" or #include "globals.c" or #include "buttonscode.c" etc. do that wisely and you'll need no .h headers nowhere.

That sounds much easier although if you are talking make file stuff the IDE handles that although yes if I don't declare functions before they are called there will be an error and putting functions in other non main.c files seems to amount to appending those files after the main function. I assume the preprocessor runs through all files and picks out any global variables declared. So including a c file would make life much easier.
https://www.simonselectronics.co.uk/shop
Varied stock of test instruments and components including EEVblog gear and Wurth Elektronik Books.
Also, if you want to get ripped off: https://www.ebay.co.uk/usr/simons_electronics?_trksid=p2047675.l2559
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 2677
  • Country: us
Re: [C] do i need a *.h file for every *.c file?
« Reply #14 on: January 21, 2019, 01:12:57 pm »
My basic practice:

Header contains anything that the caller needs to know to use the module and nothing more.

Any globals shared by functions in the module are declared "static" to restrict them to file scope.

If there is information (e.g. array sizes) which multiple modules require that goes in a separate file.

If using function putfoo() requires using function getfoo() both belong in the same module.  Anything that might be used without ever using another function belongs in a separate module.

The reasoning is as follows:

Every piece of information should exist in one place and one place only.  This prevents making changes which are incompatible and will cause an error.

The linker includes everything contained in a file whether it is used or not.  So if all the functions are in a single file, all of the functions are incorporated in the executable and loaded into memory if a single function is referenced.  (NB:  I have seen claims that this is not true with the Gnu linker.  I don't know.  But it has been the case on over a dozen Unix systems I've worked on)

If you have multiple related functions which may be used independently of each other, rather than a header for each module you put the modules in a library and have a single library header file. If several functions need to share a global variable, those go in a module with its own header which includes the library header.

You should only use global variables if it makes the code more readable or if the object is too large to be allocated on the stack as an automatic variable (i.e. large arrays).  If you use a global,restrict the scope of the variable as tightly as possible using "static".

Remember, you are writing something which will need to be read at some time in the future.  You want to communicate as clearly as possible to the reader.

I rarely use globals unless forced to by the limitations on the size of automatic arrays.  However, I once wrote a parser for an ad hoc data format that what complex.  The resulting code was a loop with a long If-elseif block.  Each conditional contained a function call.  As I was finishing it up I observed that of a dozen or so functions, all of which took the same 4 parameters,  two of them had 6 parameters.  So I made the 4 shared parameters file scope globals so that anyone reading the code in the future would immediately see those two functions were different.

So I changed from:

if( foo_1(a,b,c,d) ){
}elseif( foo_2(a,b,c,d){
}elseif( foo_3(a,b,c,d){
}elseif( foo_4(a,b,c,d){
}elseif( foo_5(a,b,c,d,e){
}

to


if( foo_1() ){
}elseif( foo_2(){
}elseif( foo_3(){
}elseif( foo_4(){
}elseif( foo_5(e){
}

If you have a number of related functions which can all be used without using any of the others, put each function in its own .c file and put all the function prototypes and other information needed by the caller such as sizes in a library .h file.  If some group of modules need to share information that the other modules don't need, create a separate header for those.

In summary, a large library might have several dozen .c files, a library .h file and a couple of .h files only included by a few files.

You should get a copy of the C standard if you don't already have one and read it any time you are doing anything you haven't been doing all day.  Study the varied effects of "static" at file and function scope.  Pay close attention to anything that is "undefined" or "implementation defined" and avoid doing the former at all times and the latter unless you absolutely have to, in which case guard it with a #ifdef  _foo_system_ so that it will have to be looked at to make it compile on a different system.

As for the comments made while I was writing this.  Having had to fix a few million lines of code written with that mindset, *please* don't do that.  It causes all sorts of headaches.  If you program well, you write the code and then use it for years without ever making any changes.  Having written a pair of 15,000 line libraries which continued in service for over 15 years with only one change and *no* bugs reported I know ti can be done.  The one change was in a function that did the following:

errno = 0;

str = getcwd( str ,len(str) );

if( ernno){
    fprintf( stderr, "getcwd() failed/n" );
}

An OS update by Sun resulted in errno being set non-zero even though the call had succeeded.  The friend who was still maintaining the code changed it to test if a  null was returned.  He told me about it over a lunch several years after I wrote the code.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10303
  • Country: gb
    • Having fun doing more, with less
Re: [C] do i need a *.h file for every *.c file?
« Reply #15 on: January 21, 2019, 01:17:59 pm »
So obviously I will split my project into several c files but do I really need a header file for each? If i list the various function prototypes in main.h will that suffice?

Absolutely not.

It is normal to have header files without corresponding c files. A classic embedded example is a list of i/o ports.

It is normal to have one header file and multiple c files. A classic example is a "module" or "subsystem" that is complex internally but which is simple for a clients to use.

The principle is that you only put in the header file the minimum necessary for the clients to be able to use the module. That published information defines the guarantee functionality that your module is making to the clients. Those guarantees should be preserved over time, as the client and module mutate asynchronously with each other.

The less you guarantee, the more freedom you have to change the internal implementation without the client noticing.


Quote
a function produces a value of a tacho signal frequency, that tacho value is used by a speed setting function to correct a speed. tacho is therefor a global variable as two functions have access to it.

Cleaner if you could pass the tacho as a variable to the two functions. Alternatively, if each of those two functions needs the instantaneous tacho reading (i.e. not the tacho reading when the function was called), hide the tacho variable inside a function (getTachoReading()) that is published in a header file. That way you are at liberty to enhance/change the tacho reading, should that prove desirable.

Be careful if a variable can be updated in one (or more) place and read in other place(s), especially if the variable is longer than the natural word length - that's a classic cause of subtle unreproducable errors. Hiding the variable inside a function(s) can, with care, mitigate that problem.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 2677
  • Country: us
Re: [C] do i need a *.h file for every *.c file?
« Reply #16 on: January 21, 2019, 01:46:47 pm »
Comment delimiter trivia:

/***************************************************************\
   This is a free form comment block.   You can make changes
   without having to fiddle with the comment delimiters and
   it makes the start and end of the comment block obvious
   to the reader.
\***************************************************************/

I got the idea from "C Elements of  Style" by Oualline, though he left out the top right and lower left slashes.  I use it for the file header comment and at the start of some exotic algorithm to explain what it is and provide
literature references.

Other good books:

The Elements of Programming Style
Kerighan and Plauger

C Traps and Pitfalls
Andrew Koenig

Expert C Programming: Deep C Secrets
Peter Van Der Linden

The last book shows how to call a function via a pointer to the function.  executing a table of function pointers until you hit a null pointer is very useful if at the start of the program you don't know exactly what functions need to be called but after you know it does not change.  For example a program that lets the user define the input or output data format.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 13948
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [C] do i need a *.h file for every *.c file?
« Reply #17 on: January 21, 2019, 02:46:51 pm »
Keep in mind that you can include a .c into a .c simply #include "pwm.c" or #include "globals.c" or #include "buttonscode.c" etc. do that wisely and you'll need no .h headers nowhere.

No that won't work. If i include a c file in atmel studio it claims to find the same function twice, I guess because it has already added it to the project so at least one header file with function prototypes is required.
https://www.simonselectronics.co.uk/shop
Varied stock of test instruments and components including EEVblog gear and Wurth Elektronik Books.
Also, if you want to get ripped off: https://www.ebay.co.uk/usr/simons_electronics?_trksid=p2047675.l2559
 

Offline mvs

  • Regular Contributor
  • *
  • Posts: 182
  • Country: de
Re: [C] do i need a *.h file for every *.c file?
« Reply #18 on: January 21, 2019, 02:57:27 pm »
I assume the preprocessor runs through all files and picks out any global variables declared.
No, it does not.

So including a c file would make life much easier.
You can include what ever text file you want, preprocessor will just copy the content of it in place of your #include statement. But there is no reason to include *.c files, since they are usually compiled to objects on their own (if you include them in your project or make file). Having multiple definitions of variables and functions may lead to linker errors.
« Last Edit: January 21, 2019, 03:05:40 pm by mvs »
 

Offline legacy

  • Super Contributor
  • ***
  • Posts: 4349
  • Country: ch
Re: [C] do i need a *.h file for every *.c file?
« Reply #19 on: January 21, 2019, 03:16:30 pm »
The linker includes everything contained in a file whether it is used or not. 

it depends by the toolchain. SierraC does it, gcc&binutils do not since they try to optimize so they removed unused code.

this is the reason why for the Not-Yaroze BSP contained in the OpenBIOS of Playstation1 we had to create a dummy module in order to fool the compiler not to remove symbols that you are not using in the BSP whose code was burned in the ROM (yep, we replaced the EPROM with a flash)

Concerning applications ... well once the toolchain got stabilized there was no problem, and it was also easy to build the file and serially upload it to the console into the ram.

The Japanese version of the Playstation1 has a serial port as well as a port that exposes a window to the CPU's addresses. It was useful for developing a RAM-emulator in order to speed-up the uploads.

Unfortunately, then Sony decided to remove  both the ports  :palm:

Anyway, the build-up of the application was not tricky, you just needed to link the application with the crt0, lib_BSP (which only contains symbols pointing entities defined in the ROM) and libc (might use BSP entity, or new primitives defined in the libc itself) and you were ready to play.

Creating the BSP was a completely different matter because it required a trick. In fact the BSP was contained in the ROM, physically 512Kbyte, mainly written in assembly, with an attached BSP written in C. Assembly has no problem, but the C stuff contains a collection of functions and global variables, and the problem *is* that none or just a few of the functions are invoked by something, and the "main()" was just a empty function to fool the linker, therefore mips1le-softfloat-2.95.1 (yeah, v2.95 .. 10 years ago) was tempted to produce an empty module.

At the first attempt, we had more than 200 functions defined in our C sources and, once compiled and linked, we get an empty binary X___X

Digging deeper, we found the workaround-trick: we filled the main-function which a list of function calls and global variables initialization, so the linker was happy and didn't remove them.

Without this trick, the linker had thought they were "useless" references because never called at compile time.
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 4840
  • Country: de
  • A qualified hobbyist ;)
Re: [C] do i need a *.h file for every *.c file?
« Reply #20 on: January 21, 2019, 03:20:24 pm »
Typically the .h files are meant to contain stuff which is common to several .c files. But in cases such as a driver for a specific LCD controller a dedicated .h for commands and bits/flags is a good idea also. And I'd recommend to learn about precompiler directives to manage your source.
 

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • Posts: 2133
  • Country: tr
Re: [C] do i need a *.h file for every *.c file?
« Reply #21 on: January 21, 2019, 03:35:38 pm »
Keep in mind that you can include a .c into a .c simply #include "pwm.c" or #include "globals.c" or #include "buttonscode.c" etc. do that wisely and you'll need no .h headers nowhere.

No that won't work. If i include a c file in atmel studio it claims to find the same function twice, I guess because it has already added it to the project so at least one header file with function prototypes is required.

Sorry, I can't help with that IDE, I only know how to use gcc and a text editor, and gcc does not include other files willy-nilly.

But you can put the prototype(s) in the .c just before the function with the (forward) function call:

Code: [Select]
//Forward call declaration
int forwardCall (int);

int afunction (void) {
    [...]
    return forwardCall(27);
}




[...]

int forwardCall (int a) {
    [...]
}
« Last Edit: January 21, 2019, 03:37:51 pm by GeorgeOfTheJungle »
git diff *
 

Online rstofer

  • Super Contributor
  • ***
  • Posts: 6658
  • Country: us
Re: [C] do i need a *.h file for every *.c file?
« Reply #22 on: January 21, 2019, 04:48:59 pm »
Short answer, yes, you need a .h file for every .c file except main.c.  Attempts to #include .c files will ultimately be a disaster  - if it even works the first time around.

The .h file will have prototypes for public functions and say nothing about private functions inside the .c file.  The idea is to provide as little information about the internal workings as possible.  Of course, the .h file has to be included in its mating .c file to verify that the prototype matches the actual function.

There may be other .h files for things like port definitions and these aren't associated with any particular .c file.

Global variables might be considered a bad thing in that any function can access them in any way it wants including changing the value.  Maybe the value isn't supposed to be changed by random code.  That's the reason that C++ implements private variables and getter/setter functions.  The class wants to control access to the variable and its value.

Instead of exposing a global variable, you write a function that returns the value and another function that sets the value.  Now your getter/setter functions can control what values are stored.  Or, you can change the implementation of the getter/setter functions to do something more complex like queue the values (serial port, for example) and the user never needs to know.  When some piece of code wants the next char, it doesn't need to know how or where it was stored.  It calls the getter function and that's all it needs to know.

Yes, hanging a global variable out in the wind is easier, in a Fortran kind of way, but it isn't better.

Hide everything, expose little, keep modules isolated through a well defined interface (the .h file).

Einstein was right: Code should be as simple as possible.  But no simpler!
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 2677
  • Country: us
Re: [C] do i need a *.h file for every *.c file?
« Reply #23 on: January 21, 2019, 05:02:24 pm »
@legacy

Interesting.  All my work was on workstations and super computers.  I  built stuff using a very large fraction of the development tool chains during the workstation wars.  Oil companies tended to buy just about everything.  Some of it was gratuitous, but in a lot of instances if you wanted to run a certain 6-7 figure application you bought whatever it ran on.  So everyone running reservoir simulations had AIX systems. All the seismic interpreters had Suns.  Anyone doing visualization had large SGI systems.  And a 3D "cave".  Those were cool.  Complete immersion  with 3D imagery on 3 or 4 walls.

But as your post makes clear.  Whatever tool chain you are using, you need to know exactly what it is doing.  And you have to be prepared for another tool chain to do things completely differently.  I can easily see the Gnu tool chain failing because it decided to delete all the functions.

Consider the case where you are executing a table of function pointers which gets an initialization from an array if certain run time conditions are met.  That's a contrived case though I did do it to speed up user defined format processing of multimillion line text files by a factor of 6.

For Simon's benefit I've attached photos of the section of my library devoted purely to C programming.  Those were bought back when you could go to a bookstore and read it for 20-30 minutes before deciding to buy it, so they're all good.  Some are dated as they deal with porting from 16 bit to 32 bit systems.  Of course, now it's 32 to 64, so the techniques are still relevant.

The software engineering section is 2-3 times bigger, but the quality is also much more variable.  Some things like "Design Patterns", I only bought because the people I was working with were very enamored with it.  I'd seen it when it came out, looked at it briefly and put it back on the shelf.

@rstofer  If the only thing in the .h file is a function prototype you do *not* need a .h for every .c.  But including .c files is bad news unless you are working on code which has to run on systems with *extremely* different IOCTL implementations.  In that particular case,

#ifdef _system_a_
#include "system_a_ioctl.c"
#endif

#ifdef _system_b_
#include "system_b_ioctl.c"
#endif

is useful for avoiding having the "#ifdefs scattered all through a single file.

To paraphrase White and Strunk  "Sooner violate any of these rules than commit something truly barberous."
 

Offline SimonR

  • Regular Contributor
  • *
  • Posts: 111
  • Country: gb
Re: [C] do i need a *.h file for every *.c file?
« Reply #24 on: January 21, 2019, 06:26:56 pm »
The short answer to the question is NO you don't need one header per c file.

In fact, and this will really put the cat among the pigeons, you don't actually need header files at all. Although that is probably very bad practice.

An explanation of why this is may help you understand how you might choose to use headers.

In a C file every item is known to every other item in that file provided it is declared in the file before the item that uses it. The items in this file cannot be seen by any item in any other file.

If an item in another file wants to use something in this file, function or variable, then it must use an extern keyword before the line at which it is used.

every file that needs to access something in another file needs to use an extern declaration. The same goes for constants, you need a #define in every file that needs it.

Now clearly this gets out of hand very quickly and so we choose to put the externs and #defines in a header file so they are declared only once and every file that needs the declaration just includes the right header. Plus you can do lots of other stuff with headers.

After that its up to you what you put in the header and how tidy you want to be which is one of the reasons C is difficult to master as there is no right answer.
C is a cake you can cut many different ways, all are correct but some are better than others.

And before anyone complains about extern being used on functions it became optional when prototypes were introduced. You still needed it in K&R C. You choose to use it in ANSI C or later

The slightly longer answer is that you tend to need one header per function module, whether the module is made up of 0ne file or many. As you grow your project you will find that the number of C files goes up quickly but the number of headers does not.
There's lots of good advice on this already.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf