Modular programming in C (nested headers) - c

I'm creating a large program that's supposed to be simulating a MIPS pipeline. I'm trying to modularize my code as much as possible to keep things simple, but I'm having trouble compiling.
Currently my program contains the files:
pipe.c --- Containing main
IF.h
ID.h
EX.h
MEM.h
WB.h
global.h --- containing global #define functions
reg.h
ALU.h
control.h
dMem.h
fBuffer.h
parser.h
bin.h
I'm new to C programming but I have protected myself against multiple includes using #ifndef, #define, #endif in every header file. My problem is that when I compile I get errors claiming: "previous implicit declaration of..."
Many of the header files are used by multiple files, so I'm not sure if this is the issue. Is there some sort of big thing that I'm missing?

an implicit declaration means that there was something that wasn't declared in a header (instead, the compiler simply found the function). a previous implicit declaration means that it's come across the declaration later, after assuming an implicit declaration for a "raw" function (or, i guess, as Doug suggests in the comments, another function with the same name).
there are a number of ways this can occur:
maybe you didn't include the header in the associated file. so IF.c doesn't include IF.h. the compiler will read IF.c and create the implicit definition. later, when it reads IF.h somewhere else, it will give this error.
maybe you use a function in a file that doesn't include the relevant header. so maybe IF.h defines myfunction(), but you use myfunction() in dMem.c and don't include IF.h there. so the compiler sees the use of myfunction() in dMem.c before it sees the definition in IF.h when included in IF.c.
without header files at all, you can get this with mutually recursive functions. see How to sort functions in C? "previous implicit declaration of a function was here" error
as Doug suggested, you define two functions with the same name (and don't have a definition in a header).
basically, somewhere, somehow, the compiler got to a function before it got to the header with the associated declaration. when it did find the header it realised things were messed up and generated the error.
(one classic source of header errors is cut+paste the "ifdefs" from one file to another and forget to change the name...)
[reading your question again i assumed you'd only listed the header files. but now i see that is all the files you have. why do you have so many more headers than source files? typically each source file is associated with one or two headers that contain the declarations for the functions it defines (although it will likely import others that it needs for support). this is unrelated to your compiler error, but it sounds like maybe you need to split your source up. it also suggests that either i have misunderstood you, or you are misunderstanding how headers are typically used.]

Related

Can I declare a function in a C source file without declaring it in the header file?

I'm only asking because I have an assignment that includes writing a function to find the inverse of a matrix. I did this using Cramer's rule and a determinant function which I added to my header file.
When I submit, however, it uses the header file we were given. So I'm trying to find out if I can somehow still use my determinant function without it being declared in the header file.
Yes, you certainly can include the declaration in your source file. Make sure that the declaration comes before the usage of the function.
Why you have to declare the function(s) in your source file if you have the respective header? Just include the header file which will/ should contain the declaration of function.
Yes, you can declare your function(s) in the source file as well which isn't in problem in small projects but it will add complexity if you somehow expands or share your project in future, its a good practice to keep the interfaces (in this case, header files) separate from the implementations (.c files).
Yes, you can declare a (global) function in a source file instead of a header.
No, you should not declare such functions in source files — each such function should be declared in one header, and that header should be used wherever the function is used (and where it is implemented, of course).
Note that if you declare the function in a source file (other than the file where the function is implemented) and do not use a header, then it becomes much more of an exercise if you ever need to alter the interface to the function — you have to search files to find it, rather than just modifying the header. Depending on the change, you may need to do more, but the old declarations scattered around the code base won't change magically, and the compiler won't spot that the definition has changed, and all hell will break loose (probably) because you have different parts of the code using different interfaces to the same function. C does not have type-safe linkage, unlike C++.
Header files are the glue that hold programs together and ensure correct operation. If you skip using a header, you lose the reliability provided by a common header which checks that the source code implementing the function matches the source code using the function.
Clearly, any function only used in a single file should be made static and should not be declared in any header. In case of doubt, make the function (and any file scope variables) static until you've a proven need to access them from another source file. And then you should ensure you define and use a header file to declare those functions (and variables, if you are really sure you need them) and use the header in the implementation source file and in the consumer source files. It may or may not be a new header; the information must be in an appropriate header.
Applying these diatribes to your problem
The header you were given constrains you, but the code outside your source file won't be using your determinant function, so it should be static and defined (and maybe declared) only in your source file — it should not be defined in the header since the judging code won't pay any attention to it. Your code that implements the interface required by the assignment can, and will, call your determinant function. But that will be in the source file, along with the determinant function. You need to declare the determinant function if it is used (called) before it is defined. If it is defined before it is used, you do not need a separate declaration, but no harm is done if you create one.
Side note
The rules for inline functions are similar to those outlined above. If need so be, you can create a static inline definition in a header file, and use that wherever the function is used. There are other ways to handle them — be cautious and make sure you understand what you're doing (and search on SO to find the answers; they're there).

Do all C functions need to be declared in a header file

Do I need to declare all functions I use in a .c file in a header file, or can I just declare and define right there in the .c file? If so, does a definition in the .c file in this case count as the declaration also?
Do I need to declare all functions I use in a .c file in a header file,
or can I just declare and define right there in the .c file?
You used "use" in the first question and "define" in the next question. There is a difference.
void foo()
{
bar(10);
}
Here, foo is defined and bar is used. You should declare bar. If you don't declare bar, the compiler makes assumptions about its return type.
You can declare bar in the .c file or add the declaration in a .h file and #include the .h file in the .c file. Whether you use the first method or the second method is up to you. If you use the declaration in more than one .c file, it is better to put that in a .h file.
You can define foo without a declaration.
If so, does a definition in the .c file in this case count as the declaration also?
Every function definition counts as a declaration too.
For the compiler, it does not matter if a declaration occurs in a .h or a .c file, because the compiler sees the preprocessed form.
For the human developer reading and contributing to your code, it is much better (to avoid copy&pasting the same declaration twice) to put the declaration of any function used in more than one translation unit (i.e. .c file) in some #include-d header.
And you can define a function before using it.
BTW, you might even avoid declaring a function that you are calling (it defaults to returning int for legacy purposes), but this is poor taste and obsolete way of coding (and most compilers can emit a warning in that case).
No, it is not necessary.
The reason of the header files is to separate the interface from the implementation. The header declares "what" a class (or whatever is being implemented) will do, while the .c file defines "how" it will perform those features.
This reduces dependencies so that code that uses the header doesn't necessarily need to know all the details of the implementation and any other classes/headers needed only for that. This will reduce compilation times and also the amount of recompilation needed when something in the implementation changes.
The answer to both questions is yes. You can declare c-functions in both header and .c file. Same with definition. However, if you are defining it in header file, you may have slight problems during compilation.
By default functions have external linkage. It means that it is supposed that functions potentially will be used in several compilation units.
However sometimes some auxiliary functions that form implementations of other functions are not designed to be used in numerous compilation units. Such functions declared with keyword static have internal linkage.
Usually they are declared and defined inside some .c module and are not visible in other compilation units.
One occasion that requires functions to be declared in a separate header is when one is creating a library for other developers to use. Some libraries are distributed as closed source and they are provided to you as a library file (*.dll / *.so ...) and a header.
The header file would contain declarations of all publicly accessible functions and definitions of all publicly required structures, enums and datatypes etc.
Without this header file the 3rd party library user would not know how to interface with the library file and thus would not be able to link against it.
But for small, trivial C programs that are not intended for use by other people, no you can just dump everything into a C file and build it. Although you might curse yourself years later when you need to maintain that code :)

Ansi C - programming language book of K&R - header file inclusion

Going through the K&R ansi C programming language book (second version), on page 82 an example is given for a programming files/folders layout.
What I don't understand is, while calc.h gets included in main (use of functions), getop.c (definition of getop) and stack.c (definition of push and pop), it does not get included into getch.c, even though getch and ungetch are defined there.
Although it's a good idea to include the header file it's not required as getch.c doesn't actually use the function declared in calc.h, it could even get by if it only used those already defined in getch.c.
The reason it's a good idea to include the header file anyway is because it would provide some safety if you use modern style prototypes and definitions. The compiler should namely complain if for example getop isn't defined in getop.c with the same signature as in calc.h.
calc.h contains the declaration of getch() and ungetch(). It is included by files that want to use these functions (and, therefore, need their signature).
getch.c, instead, contains the definition of getch() and ungetch(). Therefore, there is no need of including their declaration (which is implicitly defined in the definition).
The omission you have so aptly discovered can be a source of a real problem. In order to benefit fully from C's static type checking across a multi-translation-unit program (which is almost anything nontrivial), we must ensure that the site which defines an external name (such as a function) as well as all the sites which refer to the name, have the same declaration in scope, ideally from a single source: one header file where that name is declared.
If the definition doesn't have the declaration in scope, then it is possible to change the definition so that it no longer matches the declaration. The program will still translate and link, resulting in undefined behavior when the function is called or the object is used.
If you use the GNU compiler, you can guard against this problem using -Wmissing-prototypes. Straight from the gcc manual page:
-Wmissing-prototypes (C and Objective-C only)
Warn if a global function is defined without a previous prototype
declaration. This warning is issued even if the definition itself
provides a prototype. The aim is to detect global functions that
fail to be declared in header files.
Without diagnosis, this kind of thing, such as forgetting a header file, can happen to the best of us.
One possible reason why the header was forgotten is that the example project uses the "one big common header" convention. The "one big common header" approach lets the programmer forget all about headers. Everything just sees everything else and the #include "calc.h" which makes it work is just a tiny footnote that can get swallowed up in the amnesia. :)
The other aspect is that the authors had spent a lot of time programming in pre-ANSI "Classic" C without prototype declarations. In Classic C, header files are mainly for common type declarations and macros. The habit is that if a source file doesn't need some type or macros that are defined in some header, then it doesn't need to include that header. A resurgence of that habit could be what is going on here.

Accessing a typedef globally

I found some source code that I want to incorporate into a C program I am writing. Let's call it existing.c. This file contains a typedef for a struct that is required for a parameter to a function defined lower down in the file. I want to call this function in my file main.c. I know I could probably get access to the function by declaring a function prototype in main.c, but I will also need access to that struct definition to declare and call the function.
There is no .h file for existing.c, although I could of course make one, say existing.h. But if I put the typedef in existing.h, then it seems like I would have to put #include "existing.h" into existing.c, which does not seem correct from my understanding of header files. I thought their purpose was to make the code in a certain file available to other compilation units, and shouldn't be required by that file itself.
So I guess my main question is straightforward, how do I use the function defined in existing.c in my own file main.c? Can I do it without a header file, like by putting some kind of struct prototype in main.c, similar to a function prototype, or specify the struct as external or something along those lines?
Edit: I probably should have mentioned in my original post that one reason I was hoping to avoid using a header was so I could incorporate the existing.c file unaltered in case there are revisions of this source in the future. Judging from the answers this is not possible.
if I put the typedef in existing.h, then it seems like I would have to put #include "existing.h" into existing.c, which does not seem correct from my knowledge of header files.
That is precisely the thing to do: move the typedef into the existing.h header, then include that header in both the existing.c and in your code.
I thought their purpose was to make the code in a certain file available to other compilation units, and shouldn't be required by that file itself.
That is how the headers do their job - you include them both from the implementation file and from the code that uses that implementation.
Although it is possible to write a header that matches what was in the implementation, and use it without inclusion in the implementation file itself, this is not desirable: one reason why you include the header in the implementation is to let the compiler check the code against the function prototypes from the header, and produce errors for any discrepancies it may find.
then it seems like I would have to put #include "existing.h" into existing.c, which does not seem correct
That's the proper and correct way to do it.
You place declarations in a header file if more than one compilation unit needs those declarations, and the source code file containing the implementation is almost always one of the files you include the header file in.

Why should I include an header file? And how #include actually works? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
At first, I was writing my function in an .h file and then include it with #include "myheader.h". Then, someone said me that it's better to add to these files only functions prototypes and to put the real code in a separate .c file.
Now, I'm able to compile more .c files to generate only an executable, but at this point I can't understand why I should add the header files if the code is in another file.
Moreover, I had a look to standard C libraries (like stdlib.h) in the system and it seemed to me to store only structure definitions, constants and similar... I'm not so good with C (and to be honest, stdlib.h was almost Chinese to me, no offense for Chinese of course :) ), but I didn't spot any single line of 'operative' code. However, I always just include it without adding anything else and I compile my files as if the 'code' was actually there.
Can someone please explain me how do these things work? Or, at least, point me to a good guide? I searched on Google and SO, also, but didn't find anything that explains it clearly.
When you compile C code, the compiler has to actually know that a particular function exists with a defined name, parameter list, return type and optional modifiers. All these things are called function signature and the existence of a particular function is declared in the header file. Having this information, when the compiler finds a call to this function, it will know which type of parameters to look for, can control whether they have the appropriate type and prepare them to a structure that will be pushed to the stack before the code actually jumps to your function implementation. However the compiler does not have to know the actual implementation of the function, it simple puts a "placeholder" in your object file to all function calls. (Note: each c files compiles to exactly one object file). #include simple takes the header file and replaces the #include line with the contents of the file.
After the compilation the build script passes all object files to the linker. The linker will be that resolves all function "placeholders" finding the physical location of the function implementation, let them be among your object files, framework libraries or dlls. It simple places the information where the function implementation can be found to all function calls thus your program will know where to continue execution when it arrives to your function call.
Having said all this it should be clear why you can't put function definition in the header files. If later you would #include this header in to more then one c file, both of them would compile the function implementation into two separate object files. The compiler would work well, but when the linker wanted to link together everything, it would find two implementation of the function and would give you an error.
stdlib.h and friends work the same way. The implementation of the functions declared in them can be found in framework libraries which the compiler links to your code "automatically" even if you are not aware of it.
The C language (together with C++) uses a quite obsolete strategy for making the compiler know the functions defined elsewhere.
This strategy goes like this: the signatures of the functions etc. (this stuff is called declarations in C) go into a special file called header, and every other file which wants to use them is expected to almost literally include that header into the file (actually, #include directive just tells the compiler to include the literal text of the header), so that the compiler sees again the function declarations.
Other languages solve this problem in a different way: compiler sees all the source code, and remembers the metadata of the already compiled classes itself.
The strategy used in C shifts the task of finding all the dependencies from the compiler to the developer; it's a legacy from the old times when the computers were small, silly and slow, so this kind of help from the developer was really valuable.
Although this strategy has numerous drawbacks, and besides it's theoretically possible to change it now, the standard is not going to change, because gigabytes of code have been written in that style already.
tl;dr: it's a legacy from the 70's.
In C it is required that a function is declared before it is called. The reason this is required was that in the 70s it would just take too much time to first parse a file for all its symbols and then parse it a second time to actually compile the code. If all functions are declared before they are called one single parse is enough. However on modern system we no longer face those limitations and that is the reason why mondern languages don't have this requirement.
Imagine you have 2 files a.c b.c in your project. You implement a function foo which you want to use in both files. You can't just define the function in a.c and use it in b.c since you have to declare a function before you call it. So you would add a line void foo(); to b.c. But everytime you change the signature of your function in a.c you would have to change the declaration in b.c. To circumvent this issue it is standard strategy in C to declare all functions your file implements in a seperate header file (in this case a.h. The header file is then included by all other files who want to use that code (so b.c would use this: #include "a.h").
An #include is a preprocessor directive that causes the file to be textually inserted at the point where the #include occurs.
When linking multiple .c files that include the same header files, care must be taken to avoid multiple inclusions of the header files (textually inserting a header file more than once). The #ifndef, #define, and #endif preprocessor directives can be used to prevent multiple inclusions.
#ifndef MY_FILE_H
#define MY_FILE_H
/* This code will not be included more than once. */
#endif /* !MY_FILE_H */
I can't understand why I should add the header files if the code is in another file.
The header file contains the declarations for functions defined in the other file, which is necessary for the code that's calling the function to compile correctly.
For instance, suppose I write the following code:
int main(void)
{
double *foo = malloc(sizeof *foo * 10);
if (foo)
{
// do something with foo
free (foo);
}
return 0;
}
malloc is a standard library function that dynamically allocates memory and returns a pointer to it. The return type of malloc is void *, any value of which can be assigned to any other pointer type. free is another standard library function that deallocates memory allocated through malloc, and its return type is void (IOW, no return value).
However, the compiler doesn't automatically know what malloc or free return (or don't return); it needs to see the declarations for both functions in the current scope before it can correctly translate the function calls. Under the C89 standard and earlier, if a function is called without a declaration in scope, the compiler assumes that the function returns int; since int is not compatible with double * (you can't assign one to the other directly without a cast), you'll get an "incompatible assignment" diagnostic. Under C99 and later, implicit declarations aren't allowed at all. Either way the compiler won't translate the code.
I need to add the line
#include <stdlib.h>
which includes the declarations for malloc and free (and a bunch of other stuff) to the beginning of the file.
There are several reasons you don't want to put function definitions (or variable definitions) in header files. Suppose you define function foo in header a.h. You include a.h in files a.c and b.c. Each file will compile okay individually, but when you try to link them together to build a library or executable, you'll get a "multiple definition" error from the linker -- you've wound up creating two separate instances of a function with the same name, which is a no-no. Same goes for variable definitions.
It also doesn't scale well. If you put a bunch of functions in their own header files and include them in one source file, you're translating all those functions in one big glob. Furthermore, if you only change the code in the source file or one header file, you still wind up recompiling everything each time you recompile the .c file. By putting each function in it's own .c file, you can reduce your overall build times by only recompiling the files that need to be recompiled.

Resources