I want to define an array in a header file, together with the function using it. Not inside the function, but at the top, like a global variable.
Now I am not sure if this will work at all. How long would the array live? Is it like creating a local variable in a loop or will it stay alive since #include "said_header.h" untill the program's end?
Keep in mind that #include "headerfile.h" in C is more or less logically equivalent to opening your text editor and replacing the #include line with the entire contents of the included file.
So, header files are best used for declarations (which need to be shared between different source files, aka compilation units), while definitions are best kept in just one source file. Note that you can declare an object, and then define it, and indeed doing so when the declaration is in a header file is a good way to allow the compiler to verify that the declaration and the definition match.
so in headerfile.h you might put the declaration of your array:
extern char array[100];
and in one of your source files you might define your array:
#include "headerfile.h"
char array[100];
and in other source files you can just reference the global array:
#include "headerfile.h"
strncpy(array, "some string", sizeof(array) - 1);
Related
Let's say I'm writing a library of functions, and each function makes use of a global array to perform its duties. I don't want to expose that array to non library code, so I declare it as static like so:
library.h:
void function1();
void function2();
library.c:
#include "library.h"
static int arr[ARBITRARY_SIZE];
void function1() {...} // both of these
void function2() {...} // make use arr
If I now want to use this library in my code, I would #include "library.c" at the top of my code.
If I understand correctly, #include simply copies and pastes in place the contents of the #includeed file. If this is the case, the user's code would itself contain the static definition of arr. Given that, how would I, as the author of the library, protect my library variables? If this is not the case, please correct me about what #include does!
static keyword doesn't protect the memory used by a variable, you can pass out of a function (with visibility of it) a reference to the variable so the variable is accessible out of the block where it is defined. Then the calling code can use that reference to modify it as desired.
static serves two purposes:
inside a block in a function body, it states that: despite the variable has visibility only in the inside of the block where it is defined, its life is all the program life (it is not created/destroyed when the program enters/exist the definition block)
outside a block, it gives local file visibility (the variable name is exposed nowhere out of the definition compilation unit). But that doesn't imply that there's no accessability to that global chunk of memory. You can, if you have a pointer reference pointing to it, still modify it as you want.
#include just text includes the include file contents verbatim in the compilation flow, so everything declared static in the include file has visibility in the including file (after the point of inclussion), and locally in every compilation unit that also includes the header file. But all definitions of it are different and independent, and they don't refer to the same variable (as they are local definitions in different compilation units), as it happens if you name two local variables of different blocks (even when nesting the blocks) with the same name, they are different variables.
If I now want to use this library in my code, I would #include "library.c" at the top of my code.
That will only work if you use this library in a single source file.
As soon as you add foo.c and bar.c which both #include "library.c" and try to link them together, you would get a multiply-defined function1 and function2 symbol error (because each of foo.o and bar.o will now provide their own separate definitions.
You could fix this by making the functions static as well: static void function1() { ... }, etc. but this not how people usually use libraries, because that method causes long compile times and larger than necessary executable. In addition, if you are using this method, you don't need the library.h file at all.
Instead, what people usually do is compile library.c into library.o, #include "library.h" at the top of their source files, then link everything together.
I don't want to expose that array to non library code, so I declare it as static like so:
That is a valid thing to do, and achieves your purpose (so long as you #include "library.h" and not library.c).
Note that using global arrays (as well as most other globals) makes code harder to reason about, and causes additional difficulties when making code thread-safe, and thus it's best to use globals very sparingly.
What exactly does the preprocessor do when it encounters an #include directive in a source code?
I assume it replaces the #include with the contents of the included file, but I wanted something stronger than my assumption.
Is there any reason not to type the contents of the included file straight into the source code rather than #include it other than it being nicer on the eye?
The preprocessor will replace the #include statement with the contents of the file.
The advantage of using #include instead of simply pasting the content of the file is that, if the header file is modified, all you have to do is recompile the source file. Had you pasted the content of the file then you would have had to replace that with the new version of the header file.
Also, if you #include a file in several places (as happens with constants and type definition files) you don't have to modify all repeated declarations, the multiple times included file makes one place of change instead of several.
From my copy of the draft C11 standard section 6.10.2 paragraph 3
A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source file identified by the
specified sequence between the " delimiters.
That's the point of #include files.
Take #include <stdio.h> which is a distributed library header. If you have a suite of project source files you would possibly have to paste the content of stdio.h into every one. The whole point of #include files is that you don't have to.
Now take #include "mycommon.h" which is your local commonly used project functions. If you don't use #include every time you modify your local mycommon.h you will have to re-paste it into all your source files.
Is there any reason not to type the contents of the included file straight into the source code rather than #include it other than it being nicer on the eye?
It is not a matter of being easy on the eye.
The primary purpose of a header file is to have common declarations for function-prototypes and data-objects that are defined in separate translation units. Most non-trivial applications comprise multiple modules in separate translation units separately compiled and linked. A function or data-object must be defined in only one translation unit, but may be referenced in many - all of which must have a correctly matching declaration for the link to succeed. The simplest and least error prone method of ensuring the declarations are correct in every translation unit is to use a header file; entering the same information in multiple translation units would be very difficult to maintain.
If on the other hand your translation unit contains functions and data that are accessed only within that translation unit (or your application is a single translation unit), then the corresponding declarations may indeed appear in the same source file, and should also be declared static to explicitly disallow external linkage.
Consider for example the standard library headers such as stdio.h. You could for example enter the prototype for printf() dirctly in your code - it might look like:
extern int printf ( const char * format, ... );
but you would have to get it exactly right every time, and do it for every function you wished to use. Would you really do that!?
My objective is to instantiate an array in one C-file and have it initialised in different files only through declarative code, i.e., if the following would work, that'd be awesome:
// File1.c
int myArray[2];
// FileA.c
myArray[0] = 123;
// FileB.c
myArray[1] = 345;
The key here is that the code in FileA and FileB is not executed, but what I'd like to see is the compiler picking up these statements to initialise myArray.
What I'm really trying to accomplish here is some form of compilation-based service registration. I.e., in my real code, the array would hold pointers to functions, and my "main" (in File1.c) would not know which specific functions are compiled into the image. Via a different makefile, I would compile different combinations of my files (FileA, FileB, FileC...) and have the functions they implement available to my main via pointers.
Does anyone have an idea how to accomplish this?
You cannot initialize an array piecemeal across several files. You're only allowed one initializer in one file. So, that idea isn't going to work directly.
How can you make it work? You have pointers to functions; I assume they all have the same signature, which can be int function(int arg) for the purposes of this discussion (the details don't matter). It will be defined in a header, and that header will be needed by File1.c.
typedef int (*Function)(int arg);
Each service provider file will have an associated header, FileA.c has a header FileA.h, and so on.
The code that initializes the array could be in File1.c or in a separate file. Wherever it is, it will have to be cognizant of which modules (services) are to be linked:
#include "configuration.h"
#include "FileA.h"
#include "FileB.h"
#include "FileC.h"
Function services[] =
{
#ifdef INCLUDE_SERVICE_A
A_service_function,
#endif
#ifdef INCLUDE_SERVICE_B
B_service_function,
#endif
#ifdef INCLUDE_SERVICE_C
C_service_function,
#endif
};
size_t num_services = sizeof(services) / sizeof(services[0]);
This scheme has the benefit that there is no wasted space in the array. It also won't compile if none of the three services are requested. The build system will ensure that configuration.h includes the correct defines. The per-service headers declare the service functions.
So that gives an outline of a workable scheme.
Given the following code,
button.h
#ifndef BUTTON_H_
#define BUTTON_H_
#define true 1
#define false 0
#include <avr/io.h>
#include <avr/interrupt.h>
#include <timer0.h>
typedef struct {
unsigned char port;
unsigned char pin;
unsigned long timestamp;
} BUTTONS;
BUTTONS button_1;
BUTTONS button_2;
BUTTONS button_3;
enum BUTTONS_ID{BUTTONS_ID_1,BUTTONS_ID_2,BUTTONS_ID_3,BUTTONS_ID_COUNT};
BUTTONS* button[BUTTONS_ID_COUNT] = {&button_1,&button_2,&button_3};
void Button_init(void);
#endif //BUTTON_H_
and button.c
#include <button.h>
enum BUTTONS_state{BUTTON_STATE_UNPRESSED,BUTTON_STATE_DEBOUNCING,BUTTON_STATE_PRESSED};
int state = BUTTON_STATE_UNPRESSED;
void Button_init(void){
button[BUTTONS_ID_1]->port = PINB;
button[BUTTONS_ID_1]->pin = PINB4;
button[BUTTONS_ID_1]->timestamp = 0;
}
I get the following error : button.cpp : multiple definition of `button_1'. I know I must be doing something wrong. I am quite new at using structure the mistake must be coming from there. Basically I wanted to create button variable which I could access from my main program if need be. Is there a way to define them in my .h and initialize them within my .c and then access them from my main file?
Thank you
You've defined button1 and several other objects in your header file. If you include this header in multiple translation units (read: source files), you'll end up with one definition for each translation unit you compile. Then later, when you try to link -> KABOOM.
The simple solution is "don't put code that defines objects in your header." If you need to access them in multiple source files, you can leave the declarations, but you'll need to mark them extern. Then you can make the definition in a source file elsewhere.
You should not declare variables in header files. This is because when a header file is #included in a c file it is literally copied to it by the preprocessor.
So if 2 c files include the same h file, which in turn declares a variable, you end up with the same variable declared twice in both files. That's probably what happened here - you probably #included button.h in another c file.
The best way to make a variable application global is to declare it in only one file, and then declare it using extern in each c file where you want to use it.
In your example, do
BUTTONS button_1;
BUTTONS button_2;
BUTTONS button_3;
in one c file, and in all other c files where you want to use these vars, do:
extern BUTTONS button_1;
extern BUTTONS button_2;
extern BUTTONS button_3;
There is also other ways to do it. It's possible to use some preprocessor acrobatics and declare you variables in a header file in such a way that only in one file there are declared as global variables, and in all other files they are declared with extern. But personally I don't like this, because I do think that variables declaration do not belong in header files.
Besides, it's best to try not to use application global variables, which leads to ways of doing modular programming, low coupling and all that stuff. It's a very interesting and important topic, but is to wide for this answer.. :-)
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!