I have been reading about C for a while now and decided lets write a little add program, nothing fancy at all. My understanding of C headers is that they are "interfaces" (such as like java and other languages) but where you can also define variable that either have set values or not..
So I wrote this:
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
int main(int argc, char** argv) {
printf("hello World\n");
add(12, 18);
return (EXIT_SUCCESS);
}
int add(int a, int b){
int value = a+b;
printf("value = %d\n", value);
return 0;
}
It has a header file that looks like such:
#ifndef SAMPLE_H_GUARD
#define SAMPLE_H_GUARD
int add(int a, int b);
#endif
I thought header files, and this is where I am lost on their definition, was suppose to define the use of add, so all I would have to do is call add - From my understanding, I define the rules of add and then implement the functionality of add....
Also, A lot of the material I have read shows one header file for multiple C files. where as a lot of projects today have one header per one c, meaning Sample.h belongs to Sample.c and nothing else.
Can some one shed some light on this?
Could I have done this like so:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
int main(int argc, char** argv) {
printf("hello World\n");
add(12, 18);
return (EXIT_SUCCESS);
}
add.c
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
int add(int a, int b){
int value = a+b;
printf("value = %d\n", value);
return 0;
}
sample.h
#ifndef SAMPLE_H_GUARD
#define SAMPLE_H_GUARD
int add(int a, int b);
#endif
I believe in the book I was reading: C Programming Language they had a calculator example split up like this, my question is how does C know where add is defined? It knows the rules for it based on the header file, i think, but not where the actual implementation is ....
There example where they split of the files like such doe not have something like #include "add.c" all they do is include the header file in the files that either implement or use this functionality.
Note: obviously the calculator example and my example are going to be different but fundamentally the same - for those who have the book. I am just lost on how to use header files effectively and efficiently.
A header file in C would declare the function add for those modules that need it, but not define the function. The function is still to be defined in its own module (e.g., in your case, add.c).
So in general, to make a function foo available to several modules, you would normally:
Choose a header file (maybe it's own if there are other associated
defines, etc) to declare foo. For example, perhaps foo.h would
have void foo(...);
In some module, perhaps foo.c, you would define the complete
function foo.
In any module that wants to call foo, you would #include "foo.h"
(or whatever header you used) and call the function.
When you compile/link the code, you would make sure all modules,
including foo.o or whatever module has foo defined in it, were
present.
A declaration, given in the header file, provides (of course) the function name, the function return type as well as listing all the parameters and their types. This is all the compiler needs to know to figure out how to call the function from the calling module. At link time, addresses are all resolved so that the modules then know exactly where the function is in its own particular module.
My understanding of C headers is that they are "interfaces" (such as
like java and other languages) but where you can also define variable
that either have set values or not..
This is not correct. You cannot "define" variables - well, you can but that will cause multiple definitions error while compiling code if you include header more than once.
Could I have done this like so:
Regarding your code - both variants are correct. C language uses headers to read declarations and hence headers are optional as well. You can have your code split into as many as you want .h and .c files. Compiler will create an object file for each .c file. All .h files included in a c file are basically embedded in that C file "before compilation" i.e. in preprocessing phase. Linker then comes in picture which combines objects to produce the executable.
Please don't hesitate if something is not clear in my answer.
Related
I'm new to C programming and I just started studying functions.
Should I put each function in a .c and .h file, or can I put all of the functions and headers in one .c and .h file?
Determining where to put different parts of your code is something that comes with both your personal and the programming language experience. Considering your mention that you're currently learning about functions, let me go over a couple main factors in deciding where to put your functions.
Prototypes
When writing your code, before you can use a variable, you need to declare it first. The same goes for functions. The first, simple approach is defining a function before you use it.
int add(int a, int b) {
return a + b;
}
int main(void) {
int result = add(10, 8);
return 0;
}
Here I defined a function add() and called in the function main(). This piece of code will simply compile and run. However, what if I placed my definition of the add() function below the main() function?
int main(void) {
int result = add(10, 8);
return 0;
}
int add(int a, int b) {
return a + b;
}
This piece of code will result into a compilation error. The compiler doesn't know which add() function I'm calling in the main() function, because no add() function has been defined yet. Sometimes you can solve this problem by simply re-arranging the code. Other times that is not possible and that's why prototyping comes into play.
int add(int a, int b);
int main(void) {
int result = add(10, 8);
return 0;
}
int add(int a, int b) {
return a + b;
}
This tells the compiler there is a function add() accepting two int parameters, that will be defined later in the code. The compiler is satisfied and indeed - this piece of code compiles without an issue once again.
The #include directive
Including headers in C is a bit troublesome. It is the method of including the definitions in header files inside your .c files, and it's done in the simplest way imaginable - every #include <my_header.h> directive in your C code gets simply replaced with all contents of the my_header.h file before the compilation. For example imagine the following files:
my_header.h
// Hello, I am the my_header.h file
// I currently have no definitions
my_program.c
#include "my_header.h"
int main(void) {
// Do nothing
return 0;
}
If I compile just my_program.c, the preprocessor will examine the file before the compiler does. It will find an #include directive, look for a file named my_header.h, find it and copy its contents into the .c file simply like this:
// Hello, I am the my_header.h file
// I currently have no definitions
int main(void) {
// Do nothing
return 0;
}
Then the resulting file will be given to the compiler.
While this approach is incredibly simple and easy to implement, it makes C very prone to errors and hard to maintain, unless great care is taken. This is for example the reason include guards exist. Imagine you include two files in your main file. Now both of those two files include one, third file. After all the replacements done, you'll end up having the third file pasted twice inside your code, which will result in naming conflicts during a compilation.
This also means you technically can put any sort of code inside the header files. However, in my whole career, I was met with only one case when such code was acceptable (in a bare metal embedded system program), so I can't stress this out enough - unless you really, really know what you're doing, never put anything other than function prototypes, variable declarations, includes and macros inside a header file. Doing otherwise is the easiest way to have your code break in the most inexplicable of ways.
The conclusion
The style I've seen the most often (and also personally follow) is separating sets of functions with similar functionalities into individual .c files. This .c file contains nothing, but function definitions (i.e. the code) and a single #include directive of the header file this .c file is associated with. This keeps all the functions in a separate translation unit.
The header file with include guards (isn't needed when you don't include the file more than once anywhere, but it's a good habit to get used to) contains all the required #include directives of system libraries, other header files in your project and function prototypes of every function in the respective .c file. Whenever you then need to use those functions elsewhere, include this header file in any other header file. System libraries are generally included using <> while your own files are included using "".
As remarked by other answers, the .c file containing the main function often exists without its respective header file. All other .c files should have a header file associated. This is mostly in line with the Google's C++ Style Guide.
An example
For any smaller project, you most likely won't need more than just two files. Take these as an example:
main.h
#ifndef _MAIN_H_
#define _MAIN_H_
#include <stdio.h>
// any other includes
int add(int a, int b);
int sub(int a, int b);
int main(int argc, char *argv[]);
#endif // _MAIN_H_
main.c
#include "main.h"
int main(int argc, char *argv[])
{
int first = 10;
int second = 8;
int third, fourth;
third = add(first, second);
fourth = sub(third, first);
return 0;
}
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
If you were to add more mathematical functions, say mul() and div(), it'd be appropriate to take them all out of the main.c file and create a new pair of files - something along the way of my_math.c and my_math.h, following the same rules as the rest of your project. Then, to call the mul() function in your main function, you'd need to #include my_math.h inside main.h.
A lot of this comes with the experience. Feel free to explore other styles and try out what works the best for you. The most important part in all of this is staying consistent. Pick a style and stick to it. Best of luck in your studies!
Should every function (definition) in C have its own .c file?
No. should not, but can. It's a matter of coding-style, but it's not the preferred way to do so and unusual. It increases compilation and linking time.
Or can I put all the function (definitions) of my program in one .c file?
Yes, you can. Also again, matter of one's own coding-style.
If you got a lot or several functions in your code, you can also group the function definitions into own .c files and then link the files when invoking the compiler.
This way you keep clarity.
One way is also to keep all function definitions in a separate .c file, apart from main.c, which contains the main function.
Should I put each function in a .c and .h file?
Function definitions can't be placed inside of .h files.
.h consist only of function and other variable declarations, as well as macro definitions.
Function definitions need to be placed in .c files.
If you mean to place each function definition into an own .c file and each function declaration in an own .h, that definitely does not need to be either.
It even would confuse you all the way up.
You actually can do so, but it is definitely not recommended.
Or can I put all of the functions and headers in one .c and .h file ?
Again here you can't put function definitions in an .h file.
But you can pack all function definitions in one .c file and all function declarations in one .h file.
No! There is no need to do it at all. That would be affect your performance really badly.
Usually we only tend to create new files .h to store functions/methods that we want to use repeatedly in other projects or programs I guess.
Your program should be as follows:
Let's call this prog1.c
#include <only libs that you need>
void functionA (parameterType parameter){
//Whatever your function needs to do
}
int main(){
//this is your main function and where the program will start working.
functionA(parameters) /*Here is how you call functionA if it's void giving it's needed parameters.*/
}
Later on, with more knowledge you'll learn when you need to store or not the functions in others files to learn and keep it organized. There's no need for that now. You should focus the most on learning how they work and communicate with each other.
If you need to use functionA in other file, well then you will just need to include that .c file, like this:
In prog2.c you start it by calling out
#include "prog1.c"
I am trying to enable a set of functions from a header only if a macro is defined
I define the macro before including anything and it reaches the .h file and highlights the proper functions, but it does not reach the .c file so I can call the functions with the right prototypes but they have no definition since the .c file does not see I defined the macro
Is there some way to get this to work without having to stuff all of the .c code inside the .h file?
example:
test.h:
#ifdef _ENABLE_
int enabled_function(int a, int b);
#endif
test.c:
#ifdef _ENABLE_
int enabled_function(int a, int b)
{
return a + b;
}
#endif
main.c:
#define _ENABLE_
#include "test.h"
int main()
{
printf("%d", enabled_function(10, 10));
}
you need to use conditional compilation in both header and C file
in header file:
#define SOMETHING
#ifdef SOMETHING
int a(int);
int b(int);
int c(int);
#endif
In the C file:
#include "header_file_with_SOMETHING_declaration.h"
#ifdef SOMETHING
int a(int x)
{
/* ... */
}
int b(int x)
{
/* ... */
}
int b(int x)
{
/* ... */
}
#endif
Your source files test.c and main.c represent separate translation units. The macro definitions declared in one are not visible to the other.
Declarations that need to be visible across multiple translation units, whether of macros or of anything else, generally should go into header files that all translation units wanting them #include. It is possible to have a header that serves the sole purpose of defining macros that control configuration options, that you would create or update prior to compilation. There are tools that automate that sort of thing, but they are probably much heavier than you require for your purposes right now.
For macros specifically, most compilers also offer the option of specifying macro definitions via compiler command-line arguments.
Either way, no, your definition in main.c of macro _ENABLE_ will not be visible in test.c. (And no, you shouldn't merge test.c into test.h.)
But you should also consider whether you actually need any of that. Certainly there are use cases for cross-translation-unit build-time configuration, but what you present does not look like one of them. It is rarely very useful to suppress the compilation of a function just because you know you're not going to call it. it is usually better to either remove it altogether or to leave it, uncalled. In the latter case, your linker might even be smart enough to omit unused functions from the final binary.
"Is there some way to get this to work without having to stuff all of the .c code inside the .h file?"
and from comments...
"...but I wish to be able to define the macro in my main file and have it be visible from the .c file too
So, you are asking to #include one .c file into another .c file. This is doable with caution. But because a .c file containing the main() function cannot be #include into another .c file without invoking a multiply defined symbol error for main(...), it has to be the other way around. That is a dedicated .c file (eg. enabled.c) could be created that contains all of the #defines function prototypes and definitions. This .c file can then be #included into main.c to hopefully satisfy a variation of what you are looking for.
Following is tested source code that does this:
enable.c
#define _ENABLE_
//test criteria - then create prototype of enabled_function
#ifdef _ENABLE_
static int enabled_function(int a, int b);
#endif
#ifdef _ENABLE_
static int enabled_function(int a, int b)
{
return a + b;
}
#endif
static int use_enabled_function(int a, int b);
//This will be created with or without _ENABLE_, but its
//definition changes based on whether _ENABLE_ exists or not.
static int use_enabled_function(int a, int b)
{
#ifdef _ENABLE_
return enabled_function(a, b);
#elif
return -1;
#endif
}
main.c
#include "enable.c"
int main(void)
{
//test criteria - then use enabled_function
#ifdef _ENABLE_ //must include test for existence before using
printf("%d\n", enabled_function(10, 10));
#endif
//no need to test criteria here (tested internally)
printf("%d\n", use_enabled_function(10, 10));
return 0;
}
Alongside main.c file, I have following my_custom_data_structure.c file in my project. My my_custom_data_structure.c file contains a lot of variables, functions, etc.
I am using #include "my_custom_data_structure.c" directive in main.c.
Problem
I would like to import only single function called foo from my_custom_data_structure.c. I don't need all the variables and functions, which are declared in my_custom_data_structure.c file.
Any insights appreciated.
File structure
-
|- main.c
|- my_custom_data_structure.c
Content of my_custom_data_structure.c
#include <stdio.h>
int DELAY = 20;
int SPEED = 7;
char GRANULARITY_CHAR = 'g';
unsigned int RANGE = 3;
void foo(){
// TODO: In future, this function will print SPEED.
printf("foo works!");
}
/*
The rest of this file is filled by a lot
of code, which is not needed for main.c
*/
Content of main.c
#include <stdio.h>
#include "my_custom_data_structure.c"
int DELAY = 3;
int main(){
foo();
printf("Delay is %d", DELAY);
return 0;
}
UPDATED: Added working example
The usual way is to compile them separately. So you have your main.c, and your extra.c, and you should create a extra.h (and include it in main.c).
In this extra.h, put in declarations for anything that is to be exported from your extra.c file.
For example any functions that should be available to other files. All other functions should be declared/defined only in your extra.c as static, so that they are not available as symbols to be linked when main.c is compiled.
Normally, you don't include source files (.c) inside other source files (or inside headers). It's possible (and occasionally necessary), but it isn't usual.
Unless you've designed the my_custom_data_structure.c to allow you to specify which functions are to be compiled, you get everything in the file. For example, you could use:
#ifdef USE_FUNCTION1
void function1(void *, …)
{
…
}
#endif /* USE_FUNCTION1 */
around each function, and then arrange to
#define USE_FUNCTION1
before including the source, but that's not usually a good way of working. It's fiddly. You have to know which functions you use, and which other functions those need, and so on, and it is vulnerable to changes making the lists of USE_FUNCTIONn defines inaccurate. Of course, the source code might have blocks of code like:
#ifdef USE_FUNCTION1
#define USE_FUNCTION37
#define USE_FUNCTION92
#define USE_FUNCTION102
#endif /* USE_FUNCTION1 */
so that if you say you use function1(), it automatically compiles the other functions that are required, but maintaining those lists of definitions is fiddly too, even when the definitions are USE_MEANINGFUL_NAME instead of a number.
Create a header (my_customer_data_structure.h) declaring the functions and any types needed, and split the implementation into many files (mcds_part1.c, mcds_part2.c, …).
Compile the separate implementation files into a library (e.g. libmcds.a), and then link your program with the library. If it's a static library, only those functions that are used, directly or indirectly, will be included in the executable.
Using Qt Creator I made these plain C files just to test my understanding:
main.c
#include <stdio.h>
#include "linked.h"
int main()
{
printf("Hello World!\n");
printf("%d", linked());
return 0;
}
linked.h
#ifndef LINKED_H_
#define LINKED_H_
int linked(void);
#endif // LINKED_H
linked.c
int linked()
{
return 5;
}
The IDE shows a warning on the line of linked.h in-between #define LINKED_H_ and int linked(void); which reads
ISO C requires a translation unit to contain at least one declaration
My best guess about what this means is that any header or other C file, if it is in a project, should get used in the main file at least once somewhere. I've tried searching the warning but if this has been answered elsewhere, I'm not able to understand the answer. It seems to me I've used the linked function and so it shouldn't give me this warning. Can anyone explain what's going on?
The program compiles and runs exactly as expected.
I think the issue is that you don't #include "linked.h" from linked.c. The current linked.c file doesn't have any declarations; it only has one function definition.
To fix this, add this line to linked.c:
#include "linked.h"
I don't know why it says this is an issue with linked.h, but it seems to be quite a coincidence that the line number you pointed out just happens to be the line number of the end of linked.c.
Of course, that may be all this is; a coincidence. So, if that doesn't work, try putting some sort of external declaration in this file. The easiest way to do that is to include a standard header, such as stdio.h. I would still advise you to #include "linked.h" from inside linked.c, though.
add a header
#ifndef LINKED_H_
#define LINKED_H_
#include <stdio.h>
int linked(void);
#endif // LINKED_H
The way you wrote the code, you need to use:
extern int linked(void);
(notice the additional "extern"). That might help with the issue.
Also, the code in linked.c should be:
int linked(void)
{
return 5;
}
(Notice the "parameter" - "void").
According to IBM, you need some declaration in the header file, but you do have one. Perhaps LINKED_H_ is defined elsewhere, or the compiler is seeing that it's possible that the precompiler condition might result in an empty parse.
Perhaps this header file will work for you:
linked.h
#ifndef LINKED_H_
#define LINKED_H_
int linked(void);
#endif // LINKED_H
char __allowLinkedHToBeIsoCCompliant = 1;
As I was going through a huge source code, I came across some files where there is only one function declared in, let's say, "code.h" but in "code.c" there are many functions declared and defined.
What is the exact use of declaring and defining functions in .c files ?
How can we access one of those functions in a source file from other source file ?
It would be helpful if anyone can provide an example. Thanks
Splitting a complex routine in multiple smaller routines might make the code easier to understand and also would allow you to follow the single responsibility principle (What is an example of the Single Responsibility Principle?). By declaring and defining them only in a .c file (and declaring them static), you can hide the internal details from users.
If you, for instance, create a library, then your header could only show the public functions you'd like your users to use.
So only put your functions in a header if you'd like those functions available to anyone who includes the header.
If you'd like to keep a function internal to your .c file, seriously consider adding the static keyword as well: what is the advantage of static function?
---edit---
How can we access one of those functions in a source file from other source file ?
If the function isn't static, you could technically declare it anywhere* you'd like and use it there as well. Though, by the above argument, this would be bad practice.
Example:
a.c
int secret_a(int x)
{
return x+1;
}
main.c
#include <stdio.h>
//access a secret function from a.c
int secret_a(int);
int main()
{
printf("secret_a(3) gives: %d\n", secret_a(3));
return 0;
}
(*) anywhere allowed by the C language
How can we access one of those functions in a source file from other source file ?
That is the whole idea with defining some functions in the header, and some only in the c-file.
The functions defined in the header, can be called by other source files.
The functions only defined in the source file, can be hidden - it is a usual practice to mark functions, only declared in a source file, as static.
That makes their visibility limited to the file-scope (only code inside the same file can 'see' the functions).
The reason why this is done is to split the code into a more cleaner and sorted format so that functions concerning a particular operation can be grouped together in to one file and then called from other file. NOTE: this is not mandatory to do but a good programming practice.
Now there are two ways to do it :
1. including the files
2. Declaring the function as extern and then linking them at linking time.
1.
Including the file is the method that you are probably seeing in your code at hand. Functions are defined in one file and that file is included using #include"filename.[h/c]" and then calling the function as it were declared in the given file.
file_to_include.c
void my_func()
{
printf("Hello!\n");
}
file_that_include.c
#include<stdio.h>
#include"file_to_include.c"
int main()
{
my_func();
return 0;
}
to compile you just do
gcc file_that_include.c
using extern you can do the same but with out using the #include directive
file_to_include.c
void my_func()
{
printf("Hello!\n");
}
file_that_include.c
#include<stdio.h>
extern void my_func();
int main()
{
my_func();
return 0;
}
In this case while compiling you need to provide both files to the compiler
gcc file_that_include.c file_to_include.c
I would suggest reading up on the "extern" keyword.
From what I can understand in your question you have two files - "code.h" and "code.c". However, "code.h" only declares certain functions in "code.c":
code.h
int func1();
int func2();
code.c
int func1()
{
return 1;
}
int func2()
{
return 2;
}
int func3()
{
return 3;
}
main.c
#include "stdio.h"
#include "code.h"
extern int func3();
int main()
{
printf("%d ", func1());
printf("%d ", func2());
printf("%d ", func3());
}
Compiling using gcc:
gcc main.c code.c
yields:
main.c: In function ‘main’:
main.c:10:17: warning: implicit declaration of function ‘func3’ [-Wimplicit-function-declaration]
printf("%d ", func3());
and when executed:
1 2 3
The "extern" keyword basically tells the compiler "there is a definition for a function with this declaration" for compiling. During linking the linker will find the definition, and link to it.
This is however a clumsy way of doing it, since the caller ("main.c") needs to know what is going on in "code.c", and continually add more extern declaration, etc. etc.
So rather include functions you which to have global scope in "code.h". If there are functions in "code.c" which od not have global scope, consider making them "static".
Some more reading:
Effects of the extern keyword on C functions