0

all!

Edit: Thanks for the -1, but the "This question already has answers here:" link does exactly answer 0 of my questions, see bold marked text below. That link discusses the need of header files. I'm not asking for needing the header files, I would like to know if the below shown #includes are set correctly, esp. if I should include .c or .h files. This may result in not using .h files at all, but that's an (implicit) question. The answer of @Pepijn Kramer may help, but I'm still trying to understand and adapt to my test project.

I'm relatively new to C coding and haven't had this issue with C# or with the Arduino IDE (Windows). But right now I'm trying to set up an environment with KDevelop on a Debian 11.3 machine. My first project quite fast became a bit huge to be maintained in only a single main.c file so I tried to separate it into smaller files linked together. But I'm a bit unsure if I went the right way.

Let's have a main.c as a starting point. I created a main.h and included it from the main.c as the very first statement. Is this needed / correct?

The header file includes standard libraries like <stdio.h> et al. Then it includes the separate files of the project like "level1a.c" et al. Is it correct to include the .c files from there?

The separate files include corresponding .h files as their first statement. That way correct?

A bit tricky for me was the "2" file. I needed a collection of routines that rely on some other "1" routines. But the "1" may work without the "2" file. In the "real world" project: "1" deals with some Xlib functions (xlib_tools.h/.c) like getting Display, Windows, GraphicsContext etc. "2" goes a bit further dealing with a specific window (xlib_form_tools.h/.c) and actually mouse and keyboard events. So is it correct to include the 1.h from the 2.h file then?

I have included a "cat" of the separated files below, ending with the successful compile and run of the project. So at least I get a result. But please advise if the way is not correct.

Michael

// =============================================================================

/* main.h */

#ifndef MAIN_H_INCLUDED
#define MAIN_H_INCLUDED

#include <stdio.h>

#include "level1a.c"
#include "level2a.c"
#include "level1b.c"

#endif // MAIN_H_INCLUDED

// =============================================================================

/* main.c */

#include "main.h"

int main( int argc, char *argv[] )
{

    printf( "1st call: level 1 funcion a\n" );
    level1a();

    printf( "2nd call: level 1 funcion b\n" );
    level1b();

    printf( "3rd call: level 2 funcion a, will call level 1 function a\n" );
    level2a();

}

// =============================================================================

/* level1a.h */

#ifndef LEVEL1A_H_INCLUDED
#define LEVEL1A_H_INCLUDED

#include <stdio.h>

static void level1a();

#endif // LEVEL1A_H_INCLUDED

// =============================================================================

/* level1a.c */

#include "level1a.h"

static void level1a()
{

    printf( "level1a\n" );

}

// =============================================================================

/* level2a.h */

#ifndef LEVEL2A_H_INCLUDED
#define LEVEL2A_H_INCLUDED

#include <stdio.h>

#include "level1a.h"

static void level2a();

#endif // LEVEL2A_H_INCLUDED

// =============================================================================

/* level2a.c */

#include "level2a.h"

static void level2a()
{

    printf( "level2a\n" );

    level1a();

}

// =============================================================================

/* level1b.h */

#ifndef LEVEL1B_H_INCLUDED
#define LEVEL1B_H_INCLUDED

#include <stdio.h>

static void level1b();

#endif // LEVEL1B_H_INCLUDED

// =============================================================================

/* level1b.c */

#include "level1b.h"

static void level1b()
{

    printf( "level1b\n" );

}

// =============================================================================

miriki@lxdeb1130:~/projects/kdevelop/cpp/test_separate$ gcc main.c

miriki@lxdeb1130:~/projects/kdevelop/cpp/test_separate$ ./a.out
1st call: level 1 funcion a
level1a
2nd call: level 1 funcion b
level1b
3rd call: level 2 funcion a, will call level 1 function a
level2a
level1a

// =============================================================================
  • 1
    Did you know C and C++ are different languages? Anyway, you should compile all .C files seperately and only include their header files. Then after that you need to link all the binary files into an executable. So you need to do something in your IDE or in your makefiles to do that. – Pepijn Kramer Jul 23 '22 at 10:07
  • Hey there. Your final project should only have one `main()` function (since this is the entry point for every C program, i.e., where program execution starts). You can use Pepijn's approach, or you can also write your main.c file and `#include` all of your other header files in it, and then only compile main.c. The other header files should have all your other function definitions that you do not wish to 'clutter' your main.c file with. Just remember to only have one `main` function. – Gregor Hartl Watters Jul 23 '22 at 13:43
  • @♣Pepijn Kramer: I don't think I can compile the separate files. A gcc run would complain about a missing reference to main() at level1a.c for example. Only the main.c would compile as far as I can see. – Michael Rittweger Jul 23 '22 at 14:45
  • @Gregor Watters Härtl: As seen above in the "cat" of the files: There is, of course, only one main() residing in main.c which itself #include "main.h" where the other parts of the project are included via #include "xxx.c". One of my questions was: Is including .c the correct way? If I #include "xxx.h" there I get a bunch of errors about "used but not defined" and a few "undefined reference" after that. Or should I #include "xxx.c" from within the corr. .h file instead of the (now) other way around? – Michael Rittweger Jul 23 '22 at 14:52
  • @MichaelRittweger yeah, I'm so sorry your question was closed :( Hmmm, usually the way to do it is to have one main.c (as you have shown) and then to `#include` all the other header files you need. So, what you are doing seems to be correct! Have you defined all of your functions, or only declared them? – Gregor Hartl Watters Jul 23 '22 at 15:16
  • 1
    @Gregor Watters Härtl: The .h files all have the prototypes / declarations of the corr. .c files with the definitions - even the main.h, although not sure if needed. But specific: #include the other .h files from the main.c, perhaps removing the need of main.h at all? Right now I #include the other .c from the main.h. – Michael Rittweger Jul 23 '22 at 15:34
  • @MichaelRittweger Indeed, if your main.h file is only used for `#include`ing other files, then there is no real need for it, and you might as well `#include` the other files directly at the top of your main.c file. Please let me know if everything is working as it should. – Gregor Hartl Watters Jul 23 '22 at 17:14
  • @Gregor Watters Härtl: If I include the sub .h files from main.c I get errors, because I declare the functions in the includes, but there is no real code, because the .h doesn't seem to include the .c with the real code automagically. So I have to include the .c files with the definitions where they include their "own" .h with the declarations. I have seen a lot .h files with "real" code, not only the declarations (in fact .c files), but that's not the way I'd like to see the separation. I really want to separate the declarations (#include, #define, prototypes etc.) from the definitions. – Michael Rittweger Jul 23 '22 at 22:21

0 Answers0