source file c. Online Including one C source file in another? What can be in the header file

source file c.  Online Including one C source file in another?  What can be in the header file
source file c. Online Including one C source file in another? What can be in the header file

A similar question was recently asked to me by a colleague who is starting to program in the C language. And I thought it was a good opportunity to share my understanding this issue. Because even experienced programmers do not always have similar points of view on this matter.

This is partly a matter of taste, so if anyone is interested in how I do it, welcome under cat.

Although the “whole truth” about h-files is contained in the corresponding section of the description of the gcc preprocessor, I will allow myself some explanations and illustrations.

So, literally, a header file (h-file) is a file containing C declarations and macro definitions intended to be used in multiple source files (c-files). Let's illustrate this.

It is easy to see that functions 1 and 2, as well as macro 2, are mentioned in both files. And, since including header files has the same results as copying the contents into each C-file, we can do the following:

Thus, we simply selected the common part from the two files and placed it in the header file.
But is the header file an interface in this case?

  • If we need to use the functionality that functions 1 and 2 implement somewhere else, then Yes
  • If macro 2 is intended only for use in Unit1.c and Unit2.c files, then it has no place in the interface file
Moreover, do we really need to have two C files to implement the interface defined in the header file? Or is one enough?
The answer to this question depends on the implementation details of the interface functions and where they are implemented. For example, if you make the diagrams more detailed, you can imagine the case when the interface functions are implemented in different files:


This implementation option leads to high code cohesion, low testability, and difficulty in reusing such modules.
In order not to have such difficulties, I always treat the C-file and the header file as one module. In which,
  • the header file contains only those declarations of functions, types, macros that are part of the interface of this module.
  • The C-file, in turn, must contain the implementation of all the functions declared in the h-file, as well as private types, macros, and functions that are needed to implement the interface.
Thus, if I happened to implement the code that corresponds to the diagram above, I would try to achieve the following (the endings _c and _h in the file names were added due to the inability to use a period in the tool that I used to create diagrams):


It can be seen from the diagram that we are actually dealing with two independent modules, each of which has its own interface in the form of a header file. This makes it possible to use only the interface that is really needed in this particular case. Moreover, these modules can be tested independently of each other.
The reader may have noticed that macro 2 from the header file is back as a copy in both C-files. Of course, this is not very convenient to maintain. But to make this macro part of the interface is not correct.
In such cases, I prefer to make a separate header file containing the types and macros needed by several C files.

I hope I have been able to identify those entities that need to be placed in header files. And also, to show the difference between interfaces and files containing declarations and macros needed by several C-files.

Thank you for your attention to the material.



Depending on your build environment (you won't specify) you may find it works exactly the way you want it to.

However, there are plenty of environments (both IDEs and many handcrafted Makefiles) that expect *.c to be compiled - if that happens, you're likely to run into linker errors due to symbol duplication.

As a general rule, this practice should be avoided.

If you absolutely must # include the source (and should generally be avoided), use a different file for the file.

Including a C file in another file is legal, but not advisable unless you know exactly why you are doing it and what you are trying to achieve.
I'm pretty sure that if you post here the reason your question is being reported to the community, you'll find another suitable way to accomplish your goal (note the "almost" as it's possible that this is a solution, given the context).

By the way, I missed the second part of the question. If the C file is included in another file and is included in the project at the same time, you will probably run into the problem of duplicating symbols, why object binding, i.e. the same function will be defined twice (unless they are static).

The C language does not forbid such an #include type, but the resulting translation unit must still be a valid C.

I don't know what program you are using with the .prj file. If you're using something like "make" or Visual Studio or whatever, just make sure you set it to a list of files that need to be compiled without one that can't be compiled independently.

You can use the gcc compiler on linux to link two files to one output. Suppose you have two c files, one is "main.c" and the other is "support.c". So the command to connect these two

gcc main.c support.c -o main.out

These two files will be linked to one main.out output. To run the output the command would be

./main.out

If you are using main.c function which is declared in support.c file then you must declare it in main also using extern storage class.

Used correctly, this can be a useful technique.

Suppose you have a complex mission critical subsystem with a fairly small public interface and a lot of unimplemented implementation code. The code runs up to several thousand lines, hundreds of private functions, and quite a bit of private data. If you're working with non-trivial embedded systems, you probably deal with this situation quite often.

Your solution will likely be layered, modular, and decoupled, and these aspects can be conveniently represented and enhanced by coding different parts of the subsystem in different files.

With C, you can lose a lot by doing this. Almost all tools provide decent optimizations for a single compilation unit, but are very pessimistic about anything declared extern.

If you put everything in one C source module you get -

    Performance and code size improvements - in many cases function calls will be inlined. Even without inlining, the compiler has room to generate more efficient code.

    Channel level data and functions are hidden.

    Avoiding namespace pollution and its corollary is that you can use less cumbersome names.

    Faster compilation and linking.

But you also get an unholy mess when it comes to editing that file, and you lose the intended modularity. This can be overcome by dividing source into several files and including them in a single compilation unit.

However, you need to impose some conventions to handle this. To some extent this will depend on your toolchain, but some general pointers are

    Put the public interface in a separate header file - you should do it anyway.

    Have one main .c file that includes all child .c files. It may also include code for the public interface.

    Use compiler guards to keep private headers and source modules from being included external modules compilation.

    All private data and functions must be declared static.

    Maintain a conceptual distinction between .c and .h files. It uses existing conventions. The difference is that you will have a lot of static ads in your headlines.

    If your toolchain makes no sense, you should not specify private implementation files like .c and .h. If you use the included guards, they will not generate code and will not introduce any new names (you may end up with some empty segments as a result). The huge advantage is that other tools (eg IDE) will process these files accordingly.

The file extension doesn't matter to most C compilers, so it will work.

However, depending on your file or project settings, the included c file may generate a separate object file. When linking, this can result in double certain characters.

you have to add a title like this

#include

note: both files must be placed in the same place

You can properly include .C or .CPP files in other source files. Depending on your IDE, you can usually prevent double linking by looking at the properties of the source files you want to include, usually by clicking right click mouse over them and clicking on properties, and uncheck/check compilation/link/exclude from assembly or whatever. May be. Or you can't include the file in the project itself, so the IDE doesn't even know it exists and won't try to compile it. And with makefiles, you just simply didn't put a file in it to compile and link.

EDIT: Sorry I gave an answer instead of answering other answers :(



vote online (8)

Including a C file in another file is legal, but not advisable unless you know exactly why you are doing it and what you are trying to achieve.
I'm pretty sure that if you post here the reason your question is being reported to the community, you'll find another suitable way to accomplish your goal (note the "almost" as it's possible that this is a solution, given the context).

By the way, I missed the second part of the question. If the C file is included in another file and is included in the project at the same time, you will probably run into the problem of duplicating symbols, why object binding, i.e. the same function will be defined twice (unless they are static).

The file extension doesn't matter to most C compilers, so it will work.

However, depending on your file or project settings, the included c file may generate a separate object file. When linking, this can result in double certain characters.

Depending on your build environment (you won't specify) you may find it works exactly the way you want it to.

However, there are plenty of environments (both IDEs and many handcrafted Makefiles) that expect *.c to be compiled - if that happens, you're likely to run into linker errors due to symbol duplication.

As a general rule, this practice should be avoided.

If you absolutely must # include the source (and should generally be avoided), use a different file for the file.

You can use the gcc compiler on linux to link two files to one output. Suppose you have two c files, one is "main.c" and the other is "support.c". So the command to connect these two

gcc main.c support.c -o main.out

These two files will be linked to one main.out output. To run the output the command would be

./main.out

If you are using main.c function which is declared in support.c file then you must declare it in main also using extern storage class.

I thought I'd share a situation where my team decided to include the .c files. Our architect mainly consists of modules that are decoupled via a message system. These message handlers are public and call many local static worker functions to do their job. The problem arose while trying to get coverage for our single test cases, as the only way to implement this private implementation code was indirectly through the public message interface. With some worker features in the stack's lap, this proved to be a nightmare to provide proper coverage.

The inclusion of the .c files gave us the opportunity to get to the cog in the machine, we were interested in testing.

The C language does not forbid such an #include type, but the resulting translation unit must still be a valid C.

I don't know what program you are using with the .prj file. If you're using something like "make" or Visual Studio or whatever, just make sure you set it to a list of files that need to be compiled without one that can't be compiled independently.

Used correctly, this can be a useful technique.

Suppose you have a complex mission critical subsystem with a fairly small public interface and a lot of unimplemented implementation code. The code runs up to several thousand lines, hundreds of private functions, and quite a bit of private data. If you're working with non-trivial embedded systems, you probably deal with this situation quite often.

Your solution will likely be layered, modular, and decoupled, and these aspects can be conveniently represented and enhanced by coding different parts of the subsystem in different files.

With C, you can lose a lot by doing this. Almost all tools provide decent optimizations for a single compilation unit, but are very pessimistic about anything declared extern.

If you put everything in one C source module you get -

    Performance and code size improvements - in many cases function calls will be inlined. Even without inlining, the compiler has room to generate more efficient code.

    Channel level data and functions are hidden.

    Avoiding namespace pollution and its corollary is that you can use less cumbersome names.

    Faster compilation and linking.

But you also get an unholy mess when it comes to editing that file, and you lose the intended modularity. This can be overcome by splitting the source code into multiple files and including them in a single compilation unit.

However, you need to impose some conventions to handle this. To some extent this will depend on your toolchain, but some general pointers are

    Put the public interface in a separate header file - you should do it anyway.

    Have one main .c file that includes all child .c files. It may also include code for the public interface.

    Use compiler guards to prevent private headers and source modules from being included by external compilation modules.

    All private data and functions must be declared static.

    Maintain a conceptual distinction between .c and .h files. It uses existing conventions. The difference is that you will have a lot of static ads in your headlines.

    If your toolchain makes no sense, you should not specify private implementation files like .c and .h. If you use the included guards, they will not generate code and will not introduce any new names (you may end up with some empty segments as a result). The huge advantage is that other tools (eg IDE) will process these files accordingly.

This is fine? yes it will compile

is it recommended? no - .c files are compiled into .obj files that are linked after compilation (by the linker) into an executable (or library), so there is no need to include one .c file in another. Instead, you most likely want to make a .h file that lists the functions/variables available in another .c file and include the .h file

Programming Kozlova Irina Sergeevna

27. C++ source files

27. C++ source files

A C++ program most often includes a large number of source files, each of which contains descriptions of types, functions, variables, and constants. In order for a name to be used in different source files to refer to a specific object, it must be declared external. Eg:

extern double sqrt(double); external instream cin;

The easiest way to keep source files consistent is to put the same descriptions in individual files, which are called header (or header) files, and then include, i.e. copy, these header files to all files where these descriptions are needed. For example, if the definition of sqrt is located in the header file for the standard mathematical functions math.h and you need to extract the square root of 4, you should use the program:

Since regular header files consist of a large number of source files, they do not contain descriptions that should not be repeated.

In an include command, the filename enclosed in angle brackets, for example, refers to the file of that name in the standard directory (usually /usr/include/CC); files stored in other locations are referenced using names enclosed in double quotes. For example:

#include "math1.h" #include "/usr/bs/math2.h"

will include math1.h from the current user directory and math2.h from the /usr/bs directory.

Let's show how we could determine the output stream type ostream. To simplify the task, let's assume that the streambuf type is defined for buffering. The streambuf type is defined in the same place as the actual definition of ostream. The value of a user-defined type specifies the data needed to represent an object of that type and a large number of operations to operate on those objects. The definition consists of two parts: a private (private) part, which contains information that is used only by its developer, and a public (public) part, which is the interface of the type with the user.

From the book Programs and Windows files author Klimov A

.dbx files .dbx files store records for Outlook Express. These files, called the Message Bank, contain letters, newsgroup messages, and so on. If desired, you can copy these files to a storage medium to transfer data to another computer.

From the book Programming author Kozlova Irina Sergeevna

INF files In this article, we will look at what an INF file is, how to use it to work with other files and the registry, create shortcuts, run programs, etc. As you know, for more or less serious software product usually requires special

From the book Win2K FAQ (v. 6.0) the author Shashkov Alexey

12. Comments. Source Files A comment is a set of characters ignored by the compiler. But this set of characters is subject to certain restrictions. Within a character set representing a comment, there cannot be special characters, which

From the book Microsoft Visual C++ and MFC. Programming for Windows 95 and Windows NT author Frolov Alexander Vyacheslavovich

27. C++ source files A C++ program most often includes a large number of source files, each of which contains descriptions of types, functions, variables, and constants. In order for a name to be used in different source files to refer to a specific object, it

From the book UNIX: Process Interaction author Stephens William Richard

Files By popular demand, open the section with useful files for w2k. The section consists of two parts, the first is official patches from Microsoft (not all, but only those that seem to us the most important), and the second part, which will include all the files mentioned in the FAQ, just utilities,

From the book The C Programming Language for personal computer author Bochkov S. O.

From the book KOMPAS-3D for students and schoolchildren. Drawing, computer science, geometry author Bolshakov Vladimir

From the book Undocumented and Little Known Windows features XP author Klimenko Roman Alexandrovich

Source files The text of a C program can be divided into several source files. The source file is text file, which contains either the entire program or part of it. When compiling a source program, each of its constituent source files

From the book Programming for Linux. Professional approach author Mitchell Mark

Appendix 2 Input data for solid modeling

From UNIX Book: Development network applications author Stephens William Richard

Appendix 3 Initial data for modeling families

From Wiki-Government [How Technology Can Make Power Better, Democracy Stronger, and Citizens More Powerful] author Novek Bet

CPL files From the previous few paragraphs, you have learned almost all the theoretical calculations that are necessary to work with the rundll32.exe program. We will now list the possibilities that this program can provide the user. Let's start with a description

From the book UNIX - Universal Programming Environment author Pike Rob

1.5.4. Linux source is an open source system, isn't it? The ultimate judge of how a system works is the source code of the system itself. Luckily for us, it's available for free. Available Linux distribution may include the source code of the entire system and all

From the author's book

A.3.5. Source texts of the calculator program Listing A.3 shows the text of the program that calculates the values ​​of postfix expressions. Listing A.3. (calculator.c) The main part of the calculator/* Calculations in unary format. *//* One-line

From the author's book

Appendix D Various source codes D.1. The unp.h Header File Almost every program in this book starts with the unp.h header file shown in Listing D.1. This file includes all the standard system header files needed to run

From the author's book

From the author's book

Appendix 3 Hoc Calculator Sources These files contain all the code from "The Unix Programming Environment", by Brian Kernighan and Rob Pike (Prentice Hall, 1984, ISBN 0-13-937681-X). A separate hoc6 distribution contains any fixes that we have applied to that; the version in this file is from the book.Copyright © Lucent Technologies, 1997. All Rights ReservedPermission to use, copy, modify, and distribute this software and its documentation for