0

I know how to write .h files and include guards. I want to write a new bar123.h file that contains global variables. Assume that bar123.c does not exist.

Other header files e.g. bar.h would include bar123.h, to make the global variables visible to where they are needed.

One question is, if foo.c includes foo.h which includes bar.h which includes bar123.h, does foo.c always include bar123.h?

Another question is, how should I modify the Makefile and the Kbuild files?

I am looking for a simple hackish solution.

tech
  • 107
  • 5
  • You are probably aware of it, but just in case: remember that C *#include* preprosessor directive just puts the text in the included file to compilation. There are no fancy "import" semantics, you could just copy-paste the header file to your source code in editor and it would work the same (I know only one exception, non-standard *#pragma once*). – hyde Nov 21 '13 at 08:39
  • Thanks hyde. I actually haven't made the new header yet. Now just pasting 'extern int baz;' into multiple header files. Compiles fine but I am still getting the 'Unknown symbol baz' during runtime. ('umac: Unknown symbol baz (err 0)' on the openwrt router serial terminal Tera Term if that helps.) – tech Nov 21 '13 at 09:18
  • I wrote an answer to your comment, but you might want to update the question... :) – hyde Nov 21 '13 at 09:31
  • Thank hyde. The solution doesn't seem easy. I may try it next time. Currently going by another method. – tech Nov 22 '13 at 01:10

4 Answers4

1

A global variable must exist somewhere, and only in one place. That means it needs to be declared in one place only.

Remember: H files just tell the compiler that things exist somewhere. C files provide the actual definition of those things.

Let's say your global belongs nowhere else, we'll add a globals.c:

#include "globals.h"
int g_myGlobal;

There should be a corresponding globals.h:

#ifndef _GLOBALS_H
#define _GLOBALS_H

extern int g_myGlobal;

#endif // _GLOBALS_H

It is almost certainly an error to have a global variable declared in a .h file without extern. If you do such a thing, the compiler will try to declare that variable in every C file that includes that header, which will lead to "multiple definition" errors at link-time. (I'm assuming this is why you were asking "foo.c always include bar123.h?", and explains why it should not matter.)

main.h:

#include "globals.h"
int main() {
    g_myGlobal = 42;
}
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
1

To Answer your first query- Yes foo.c will always contain bar123.h .

Second query , In Make file the only change you need add is add this bar123.h in the list of header include file . since you dont have any new .o files being generated you dont need to change that part .

Hope it answers your queries

Srikanth
  • 447
  • 2
  • 8
  • Thanks Srikanth, very straight to the point. Can you give a link that says that foo.c will always contain bar123.h? What is this phenomenon called? – tech Nov 21 '13 at 06:51
  • It is recursively including header file , I have just quoted with my experience . If you want further reference you can go to the link http://stackoverflow.com/questions/705676/how-does-inclusion-of-header-file-happen – Srikanth Nov 21 '13 at 07:15
1

The short of it is this. You can't include a global in a header file and then have that header includes elsewhere. You'll get the nasty "re-definition" error. Unless....

This is what I do.

Header file happy.h

extern int happy; // Global variable

Main file

#include "happy.h"

int happy = 12;

Other file.c

#include "happy.h"

int happy = 10;

On question 2: That depends on the compiler. Some will implicitly add it, however, good coding would be one where you include any .h files that you are intending to use a function from.

Note* It is never a good idea to place globals in a header. The intended use of a header is struct definitions and "public" function declarations. Struct / Union etc definitions are only included in headers when it becomes necessary. Example:

typedef struct
{
    int happy;
    char sad;
} my_mood_t;

my_mood_t *what_is_my_mood( int dog_ate_my_lunch );
user2172997
  • 31
  • 1
  • 2
  • Thanks. 'Some will implicitly add [bar123.h to foo.c]' So it is not confirmed? Does gcc compiler include all the header dependencies recursively? I'm not sure if I'm using the right terminology. – tech Nov 21 '13 at 07:10
  • I think curly braces should be used instead of brackets for the last line because it is initializing the struct. – tech Nov 21 '13 at 08:49
0

From comment of OP:

Compiles fine but I am still getting the 'Unknown symbol baz' during runtime. ('umac: Unknown symbol baz (err 0)' on the openwrt router serial terminal Tera Term if that helps.)

If application linked fine, but fails to run with that error, it means that during build time linking, a dynamic library with that symbol was available. However, during runtime, that symbols is not available. A quick fix:

  • Determine what library has the symbol
  • Make sure that library exists where you are running the application, and note it's path
  • Instead of just running application, use command LD_LIBRARY_PATH=/path/to/the/library/directory application (you can also separately export LD_LIBRARY_PATH with that value, but then it will be set for every program, not just that one).

This is not the only way. You could also copy the library to system library directory and run ldconfig to update system library cache. Or you could use rpath mechanism. But start with LD_LIBRARY_PATH environment variable to get things working, before looking into these.

hyde
  • 60,639
  • 21
  • 115
  • 176