I am in the process of exploring the C programming language and have started to learn about header files.
I am working with three different files in my program. One header file and two source files:
encrypt.h
void encrypt(char *message);
encrypt.c
#include "encrypt.h"
void encrypt(char *message)
{
while(*message)
{
*message = *message ^ 31;
message++;
}
}
main.c
#include <stdio.h>
#include "encrypt.h"
int main()
{
char myMessage[] = "Hello";
printf("Regular message: %s\n", myMessage);
encrypt(myMessage);
printf("Encrypted message: %s\n", myMessage);
return 0;
}
The first line in the encrypt.c file is the #include statement:
#include "encrypt.h"
My question is why is this line necessary inside of this file. I was reading how the #include directive has a copy/paste functionality and inside of the main.c file I can see how this approach would support forward declaration for the encrypt function; however, inside of the encrypt.c file, it would seem that forward declaration of the function is not necessary, and was wondering what was the purpose of using the include directive in this situation?
I apologize if this question has been asked elsewhere and will mark as duplicate as required. Thank you for the clarification.
In your particular case, it is not necessary for encrypt.c to include encrypt.h, but it is conventional for it to do so.
The normal purpose of header files is to provide a common location for declarations that can be shared among multiple source files. This avoids inconsistent declarations in different parts of the program, and when changes need to be made, it may reduce the number of files that need to be updated.
encrypt.c does not need to include encrypt.h because the latter contains only a declaration of function encrypt(), and encrypt.c already has one in the form of a definition of that function. It is nevertheless useful, because it allows the compiler to verify that the declaration in encrypt.h is consistent with the definition in encrypt.c.
If encrypt.c defined more functions, and encrypt.h provided declarations for all of them, then it could also serve in encrypt.c to ensure that declarations of all functions therein were visible to all functions therein, thus overcoming any dependency on the relative order of the actual definitions.
Side note:
The moment you add a new source file fancy_encrypt.c which calls the encrypt() function you must have a compile guard in the encrypt.hfile:
#ifndef ENCRYPT_H
#define ENCRYPT.H
void encrypt(char * message);
#endif
Otherwise you will get a compiler error due to multiple declarations of encrypt().
Related
I'm writing a userland in C (be it minimal at the moment) and I'm making it like BusyBox where you can run a command by invoking a symlink with its name. I've got a "main" C file which includes all the other files inside it (the other files are header files) and then runs their code if the symlink name matches. I was wondering whether it is deemed OK to have functions with the same name across different header files?
For example, if I had thing1.h:
void help(void)
{
// Print help text for thing1
}
int thing1(int argc, char *argv[])
{
if (something)
help();
}
And thing2.h:
void help(void)
{
// Print help text for thing2
}
int thing2(int argc, char *argv[])
{
if (something)
help();
}
And everything.c:
#include "thing1.h"
#include "thing2.h"
int main(int argc, char *argv[])
{
if (something)
thing1(argc, argv);
else
thing2(argc, argv);
}
Would it be better to rename those help functions to thing1_help and thing2_help respectively, or is it OK to leave them as they are?
First, please understand more how the C preprocessor works and read also the documentation of cpp.
Notice that preprocessing is a purely textual operation. So you could avoid having any header files and #include directives, e.g. by copy-and-pasting things. That would be a bad idea.
So header files are mostly a conventional thing (however, the C99 standard does mandate some standard headers, like <stdlib.h> or <stdio.h>; and POSIX specifications also mandates several headers). Common practice includes:
wrapping the header file contents with an include guard (to disable multiple inclusion)
putting only declaration, not definition of (often "global") functions, types, variables in header files.
putting the definition of static inline functions in header files.
Actually, standard header inclusion (e.g. #include <stdlib.h>) could even in principle be implemented without any stdlib.h textual file : the compiler implementation could for instance query a database to process #include <stdlib.h> directive, but I know no compiler doing that.
Some people (me included) are putting #include directives (notably for standard C99 or Posix headers) inside their header files. Others are documenting the list of headers to be included before their own header files.
Look at the preprocessed form of your code (which is what most of the compiler care about, since the preprocessor is the first phase of the compiler). You could obtain the preprocessed form of everything.c using GCC with
gcc -C -E everything.c > everything.i
Then look inside everything.i with an editor or a pager.
In practice, I would suggest to make -if it is really short- your thing2 a static inline function, then to have a single (not several) header:
// file thing.h
#ifndef THING_INCLUDED_
// declarations
void help(void);
int thing1(int argc, char *argv[]);
// definition:
static inline void thing2(int argc, char**argv) {
if (something_with(argc, argv))
help();
}
#endif /*THING_INCLUDED_*/
then put the definitions of help and of thing1 in e.g. your everything.c and add there an #include "thing.h" after the others #include directives.
Both help functions should be the respective c files then it wouldn't matter that there's a name clash as they are private to the scope of that compilation unit.
In general keep code in c files and only declarations in h files.
I am developing a program in C and I need to have one .h file and two .c files that share the same name on the methods but have different implementations. So basically what I am trying to do is:
header.h --->
void f();
void d();
source1.c --->
#include "header.h"
void f(){
print("Hello");
}
void f(){
print("World");
}
source2.c --->
#include "header.h"
void f(){
print("My name");
}
void f(){
print("is Danni");
}
but I have an error of multiple declarations :(
So I was wondering if there is any kind of trick about how to do this, maybe using macros or somenthing like that.
Thanks...
Well, there are two solutions ..
The first solution (not recommended)
It is based entirely on the compilation process. You simply compile the source.c file with the main function with the source you want to use. This should work without errors simply because the compiler is not aware of the other file. This is not recommended because it provides the same functionality (at some extent), use the same header file but are seperated source files. You might risk losing one of them. Also, you have to be aware of that whenever you're compiling a program that uses that header.
The second solution (recommended)
It is based on the preprocessing step, which is much more safer than the compilation command because it works the same with any compiler options or commands.
You have to use Macro Conditionals because they're processed before compilation. The behaviour of macro conditionals is almost entirely based on variable existence or comparison.
You can use something like that:
#ifndef _HEADER_H
#define _HEADER_H
void f();
void d();
#ifndef _HEADER_H_2 /* Where this is the default behavior if nothing the macro wasn't defined */
# include "source1.c"
#else
# include "source2.c"
#endif
#endif /* _HEADER_H */
If I have a c project where my main program needs file1 and file2 but file2 also needs file1. Is there a way I can get around including file2 in both main and file1? If I have an include guard, will this prevent file1.c from being added twice?
//file1.h
#ifndef FILE1_H
#define FILE1_H
void func1(void);
#endif
--
//file1.c
#include "file1.h"
void func1(void) {
..do something
}
--
//file2.h
#ifndef FILE2_H
#define FILE2_H
void func2(void);
#endif
--
//file2.c
#include "file2.h"
#include "file1.h"
void func2(void) {
..do something
func1();
}
--
//main.c
#include "file1.h"
#include "file2.h"
int main(void) {
func1();
func2();
return 0;
}
-- Since file2 includes file1, can I do this? will it prevent repetition of file1 code?
//main.c (alternate)
#include "file2.h"
int main(void) {
func1();
func2();
return 0;
}
I'm not too concerned about problems arising if file2 decides to no longer include file1 in the future. I'm much more concerned with wasted space.
What I'd like to know is A: does the include guard prevent the code duplication and if so, there is no additional space used by including file1 in both main.c and file2.c. B: in the case that extra space is being used, will my alternate main.c work?
Quick explanation (with the note that all of this can be overwritten by people that know what they are doing):
First of all, two definitions: declaration is when you write down that something exists. For example, "int foo();" or "struct bar;". Note that we can't actually use this thing yet, we've just given it a name. As long as you declare them as the same thing, you can declare things as many times as you want! (variable declaration has its own rules).
Anything you want to use needs to be declared before you reference it.
definition is when you say what the declaration is. int foo() {asdfadf;} or struct bar{int x;}. Things can be (and often are) defined when they are declared, but not always.
In C, you must follow the One Definition Rule. Things can be declared as often as you like, but they can be only defined once per translation unit (defined in one sec). (in addition, function calls can only be declared once per entire executable).
There are very few things that need to be defined before you use them...other than variables, you only need to define a struct before you use it in a context where you need its size or access to its members.
What is a translation unit? It is all the files used to compile a single source file. Your header files aren't targeted for compilation. Only your .c files (called "source files") are. For each c file, we have the idea of a "translation unit", which is all the files that are used to compile that c file. The ultimate output of that code is a .o file. A .o files contains all the symbols required to run the code defined in that c++ file. So your c file and any files included are withing the header file. Note: not everything declared in the translation unit needs to be defined in it to get a valid .o file.
So what is in a header file? Well (in general) you have a few things:
function declarations
global definitions & declarations
struct definitions & declarations
Basically, you have the bare bones declarations and definitions that need to be shared between the translation units. #include allows you to keep this in one shared file, rather than copying and pasting this code all over.
Your definitions can only happen once, so a include guard prevents that from being a problem. But if you only have declarations, you don't technically need and include guard. (You should still use them anyway, they can limit the cross-includes you do, as well as work as a guarantee against infinitely recursive inclusion). However, you do need to include all declarations relative to each translation unit, so you will most likely include it multiple times. THIS IS OK. At-least the declaration is in one file.
When you compile a .o file, the compiler checks that you followed the one definition rule, as well as all your syntax is correct. This is why you'll get these types of errors in "creating .o" steps of compilation.
So in your example, after we compile, we get file1.o (containing the definition of func1), file2.o (containing the definition of func2), and main.o (containing the definition of main). The next step is to link all these files together, using the linker. When we do, the compiler takes all these .o files, and makes sure that there is only one definition for each function symbol in the file. This is where the magic of letting main.o know what is in file1.o and file2.o happens: it resolves the "unresolved symbols" and detects when there are conflicting symbols.
Final Thought:
Keeping code short is kindof a misguided task. You want your code to be maintainable and readable, and making the code as short as possible is about the opposite of that. I can write a whole program on one line with only single letter alpha-numberic variables names, but no one would ever know what it did...what you want to avoid is code duplication in things like declarations. Maintaining a long list of #includes can become tricky, so it is often good to group related functions together (A good rule of thumb is that if I almost always use A and B together) then they should probably be in the same header file.
Another thing I occasionally (occasionally because it has some serious drawbacks) is to use a convenience header file:
//convience.h
#ifndef CONVIENIENCE_H
#define CONVIENIENCE_H
#include "file1.h"
#include "file2.h"
#endif
The convenience header file only has other header files in it, which ensures that it NEVER contains code, which makes it a little easier to maintain, but still kindof a mess. Also note that if you do the include guards in file1 and file2, the convienience guard isn't nessisary, though it can (theoretically) speed up compilation.
Why can't you have a single header where you can put both your functions func1() and func2().
Just include the header in different files.
Didn't get what you mean by code duplication.
//file1.h
extern void func1();
extern void func2();
//file1.c
#include<file1.h>
void func1()
{`
enter code here`
}
//file2.c
#include<file1.h>
void func2()
{
}
//main.c
#include <file1.h>
main()
{
func1();
func2();
}
I have the following code layout
header.h
#ifndef _header_h
#define _header_h
void empty(float *array, int l)
{
int i;
for (i=1 ; i<=l ; i++)
{
array[i]=0;
}
}
#endif
and two files (lets call them file1.c and file2.c)
#include "header.h"
void function/*1 or 2*/(){
....
empty(a,b);
....
}
So compiling works fine but the linker command fails as the compiler says that there is a duplicate function definition. How can I avoid that with still using the header file? It is working fine when I only define the function in the header and create another .c file containing the full function. I always thought declaring it in the header is the way to go.
I always thought declaring it in the header is the way to go.
Yes, it is. Declaring it in the header is fine. It is not any good to define it in a header, though. (unless it's static inline, but you probably don't want to do that these days.)
You should never have things in a header that require memory in the running program. This is a rough way of specifying it, but it works pretty well in practice.
In other words, the header should only have the prototype for the function, which is a compile-time thing that doesn't "exist" in the running program (unlike the code of the function itself, which of course exists at runtime):
void empty(float *array, int l);
Then put the code in a separate C file, which you compile and link separately.
You have the function empty defined as a global symbol in the header. This means it will be a visible symbol in all compilation units that include it. There are three general workarounds:
make it a static function
static void empty(...) {...}
put the implementation into a separate compilation unit
in header.h:
void empty(float *array, int l);
in empty.c implement it
instruct your linker to ignore duplicate symbols. This differs from linker to linker, consult man ld.
On OS X: -m flag.
On Linux: -z muldefs
I am working on a C project in which part of the code is generated by a different application. The separate files would contain the following:
Type definitions, main(), and other functions
Variable declarations (whose type definition is in the file above) and functions to work with those variables
As mentioned, the information in the second file is generated by a different program, but it uses the type declarations in the main file. Similarly, the main program uses the variables and functions defined in the second file.
I have tried using the "include" and "extern" statements but have not been very successful at it. Since the two files are getting information from each other, would it be more useful to break them up in three files as follows?
1) Type definitions
2) Variable declarations (using the types defined in file 1) and related functions
3) Main() and the rest of functions that use the two above files
If this was the way to go, how would it work? Would it use include or extern, and how would I need to use these clauses?
Any help you can provide is greatly appreciated. Thank you!
There is nothing wrong with the layout you are suggesting. Perhaps some clarification on what extern and #include do would be helpful.
1) #include is a preprocessor directive which essentially says: `take the named file and pretend it is pasted in place of this directive'
2) extern is a C reserved word. Not to get into too many technicalities, but its meaning is: `the variable named in this statement is defined in a different place'. The space for a variable is reserved by the compiler exactly once, so if a function needs access to the variable in question, some information is needed before the definition is seen by the compiler. An extern declaration has enough information for the function to use the variable and the linker makes sure that a correct variable is used at a later stage.
So in your scenario, the file with type definitions will be #include'd in every file that refers to those types. If you want to collect all the variable definitions in one file, which will be compiled separately from other parts of your project, any file that uses those variables and will be compiled separately, needs to be supplied an extern declaration for each variable defined elsewhere. Note that if you simply include th file with variable definitions, the compiler will see the definition twice (first in the file with the definitions, then in the file that includes it) and assume you are trying to define each variable twice and will issue an error.
Finally, here is a simple scenario (it does not really make sense and is in bad style):
a.c---------
#include "t.h"
mytype a;
mytype b;
int f( int x, int y ) {
return (x + y)*a - b;
}
m.c---------
#include <stdio.h> // for stdout
#include "t.h"
#include "v.h"
int main () {
fprintf( stdout, "%d", a + b - f(1, 2) );
return 0;
}
t.h-----------
typedef int mytype;
v.h-----------
#include "t.h"
extern mytype a, b;
int f( int, int );
v.h and t.h can be combined (it is a question of style and the project requirements). Note that a declaration of f in v.h has an implied extern in front of it.
As outlined in a comment, you will almost certainly need a header — call it header.h — which will be included in both the file containing the main program (file 1, call it main.c) and in the generated file (file 2, call it generated.c).
The header file will contain the type definitions and shared function declarations (and, perish the thought, declarations for any global variables). It will be self-contained and idempotent (see, amongst others, the Stack Overflow questions What are extern variables in C?, Should I use #include in headers?, How to link multiple implementation files in C?, and Linking against a static library).
Both main.c and generated.c will include header.h. To ensure that header.h is self-contained, one (or both) of the files will #include "header.h" as the first header.
Finally fixed. If anybody else has the same problem, I followed Alexsh's steps but I also had to include guards in my .h files to prevent redefinitions (otherwise it wouldn't compile). Thank you very much to both Alexsh and Jonathan for their help!