home made library questions

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi again.
I have a few questions about writing my own libraries. How do I write them so that they still work if I accidentaly include them more than once? Also how do I include my interrupts.c file since it has no function prototypes and therefore nothing in the .h file? Currently I have a globals.h file in which I declare all my global variables, is this the right way to do it or do I have to make a globals.c file as well. If so what do I put in my ".h" file?
thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> How do I write them so that they still work if I accidentaly include
> them more than once?

For a *true* library, that should not matter, as the linker only pulls
those object modules out of the library that will help resolving an
undefined global symbol.

I guess you don't have a real library, but simply specify the
individual .c files somewhere in the Makefile. In that case, there's
no help. Your process should ensure you've only got each file once.

> Also how do I include my interrupts.c file since it has no function
> prototypes and therefore nothing in the .h file?

The .h file is completely unrelated to this. It doesn't trigger any
decision about linking, it's only for the compiler to declare other
module's public interfaces (so it can check the syntax).

Normally, you'd only specify that file in the list of C files that are
used to build your job. Note that a file that defines interrupt
vectors is a poor candidate for a true library though, as it will
require very special tricks to cause the linker pulling that file out
of the lib.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Normally, you'd only specify that file in the list of C files that are used to build your job. Note that a file that defines interrupt vectors is a poor candidate for a true library though

sorry maybe I used the wrong term. I'm trying to separate my code into multiple files organized by function.What I meant by library was the .h and .c file pair. my problem is that some of these modules use others and I'm trying to make sure that I dont get something weird when I compile. :shock:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are linking the object modules compiled out of each of
these source files because you're specifying all their names on
the linker command line. (The Makefile arranges that four you.)
That causes all functions to be included. (This is the biggest
difference to a true library, where only those object modules
will be included from the library that satisfy an undefined
reference.)

As to mutually referencing each of these functions, that's no
problem. That's exactly where the .h files are for: they contain
the interface declarations for everything, so the compiler knows
what's contained in the other files by inluding the respective .h
file. It doesn't need to see each individual *implementation* file
at that stage, as long as all implementation files eventually passed
the compiler, and made it into object modules to link. If you
specified a .h file somewhere that declares some interface but
forgot to also compile and link the respective .c file, the linker
will complain about an undefined reference (even though the
compiler did not complain).

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Once you sort out the issues Jorg is talking about, you need to settle on a .h file methodology. One rule you could choose to follow is never put a #include directive in a .h file. That means that if foo.c includes bar.h, and bar.h depends on fumble.h, then foo.c must also include fumble.h before bar.h. Ok, that sounds confusing, but type in the code and it will make sense. If OTOH you choose to let .h files include other .h files, then there is a standard idiom:

/* this is bar.h */
#ifndef BAR_H
#define BAR_H
/* ... bar.h stuff goes here ... */
#endif

That way, you can include bar.h multiple times but only the first one is actually processed. Personally, I usually go with never letting a .h include a .h file. I like to be able to look at the top of a .c file and see all the dependancies.

Also, I avoid putting anything that generates code or allocates memory in a .h, I keep it purely definitions. For example, for globals I will have a globals.h that is only declarations for .c files to reference, and globals.c where the actual memory allocations exist.

-dave

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I generaly just keep a pile of function defs in my .h files anyway. I'm a bit hazy on doing this kind of thing because we didnt cover it in my C++ class and they stopped offering C for which it was a prereq before i had a chance to take it. On a related note : should I put a function definition into a .h file even if that function is only used internaly to that module? Currently ive got it arranged so that the function code is above the function that uses it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Should I put a function definition into a .h file even if that
> function is only used internaly to that module?

Btw., it's a function *declaration* you're putting there. (Except for
inline functions, where declaration and definition are always the
same.)

Nope, header files are supposed to declare public interfaces. So
anything private to one compilation unit does not belong there. It's
considered good style to define/declare any module-internal functions
and objects "static", so their names are not visible outside anyway.
So a typical scenario might look like:

foo.h:

#ifndef FOO_H
#define FOO_H

#include 

extern uint8_t foo_status;

void setfoo(uint8_t);
#endif /* FOO_H */

foo.c:

#include "foo.h"

uint8_t foo_status;

static uint8_t old_status;

static void mumblefoo(void);

void
setfoo(uint8_t newfoo)
{
   if (newfoo > 2) {
      old_status = foo_status;
      mumblefoo();
      foo_status++;
   }
}

static void
mumblefoo(void)
{
  foo_status = 0;
}

In short:

  • The public header file foo.h declares all exported interfaces, that's the global variable foo_status, and the public function
    setfoo().
  • The implementation file foo.c first includes foo.h. If anything in foo.h would not be consistent with the actual implementation,
    the compiler can complain about it.
  • Global data are defined on top of the file.
  • (Optional) Internal functions get a prototype declaration marked "static" on top. This supplies a prototype for the compiler to
    verify the implementation against. This step is optional in case
    the actual function definition inside the module foo.c would precede
    any use of this function.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the case of my global.h module, is it ok to just have a .h file like this:

//globals.h
int x;
char y;

or should I have a a .h and a .c file like this:

//globals.h
extern int x;
extern char y;

and this

//globals.c
int x;
char y;

?
and if im #include-ing my globals.h file into every file that uses a global do I still have to declare the variable extern within the function that its using?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The first case is acceptable in a few C implementations, but the second case is
acceptable to all C implementations, so I recommend the second.

Quote:
do I still have to declare the variable extern within the function that its using?

I'm not sure what this means. There's nothing wrong with having "extern int x" (declaration)
and "int x" (definition) in the same source file, so standard practice is to go ahead and include
globals.h in globals.c and then define x and y there. (That allows the compiler to check for typos.)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Q

Quote:
uote:
do I still have to declare the variable extern within the function that its using?

I'm not sure what this means.


What I meant was, that since my global header file already declares

//globals.h
extern int x;

do I then in my function that uses this variable have to

#include "globals.h"
int foo(void)
{
extern int x;
x++;
.
.
.
return 0;
}

or can I simply

#include "globals.h"
int foo(void)
{
extern int x;
x++;
.
.
.
return 0;
}

Another question: if i define a structure and want this type of struct to be definable anywhere how do I define it in my globals module? Basicaly I've writen my code so that my configuration structure gets modified by my ui() functions. Originaly I had it all done with global variables since there werent that many parameters but as i was moving downward from the top it started to get confusing, so now I'm trying to redo everything so that its a bit neater.Unfortunately my K&R doesnt seem to mention how to do this.
My best guess is doing something like

//structs.c
struct thing
{
int l;
int w;
int h;
}
//structs.h
extern struct thing;

Is this anywhere near right?