5

I have a few commonly used macros that are universally needed in just about every C file I write. Currently I am copying them into each file I need them in. This is likely a bad idea because I'm eventually going to need to change one of them and then I'll end up with inconsistently defined macros between files.

Is there a way to essentially make a header file for macros? I tried to make a header with all my macros in it and include that, but I still get compiler warnings.

UPDATE: The specific warnings I get are implicit declarations of functions such as V4 from the second example.

An example:

file1.c:

#define COMMON_NUMBER 1

file2.c:

#define COMMON_NUMBER 1

//...

fileN.c:

#define COMMON_NUMBER 1

//Oh wait, it should have been 2 all along..... *facepalm*

A better example:

file1.c:

#include "usefulmacros.h"

char* prog;
int optv;

int main(){
  prog = strdup(argv[0]);    
  optv = 4;           // This would be parsed from # of "-v" in argv[]
  return 0;
}

void functionA(){
  int dumberror = 1;
  V4("This is a fairly verbose error: %d",dumberror);
}

file2.c:

#include "usefulmacros.h"
extern char* prog;
extern int   optv;

void functionB(){
  int differror = 2;
  V4("This is a different error: %d",differror);
}

usefulmacros.h:

#ifndef USEFULMACROS
#define V4(str, ...) if(optv >= 4){printf("%s: "str,prog,__VA_ARGS__);}
#endif
Huckle
  • 1,810
  • 3
  • 26
  • 40
  • 6
    What kind of warnings are you talking about here? Shall we guess? – Jeff Mercado Mar 05 '12 at 20:30
  • 1
    In case you haven't heard, there are very few jobs for which macros are the best tool, and they can cause a lot of problems. For instance, this `COMMON_NUMBER` could be a `const` global variable (or better). – Beta Mar 05 '12 at 20:32
  • @JeffMercado: I updated my question with a better example that illustrates what is happening in a more specific sense. – Huckle Mar 05 '12 at 21:13
  • @Huckle Please see an edit to my answer - I think you are missing an important `#define` in your `usefulmacros.h`. – Sergey Kalinichenko Mar 05 '12 at 21:59
  • @Beta Not if it is to be used in preprocessor conditionals or integer constant expressions (case labels, array sizes, bit-field sizes, static assert values,...). C++ allows expressions based on const objects in the latter group, but standard C doesn't. – Petr Skocik Feb 06 '20 at 11:13

4 Answers4

9
#ifndef COMMON_INCLUDE_FILE
#define COMMON_INCLUDE_FILE

#define COMMON_NUMBER 1
#define OTHER_COMMON 2

#endif

In C, where macros are a little more pervasive than C++ where you'd want to do it with a static global, the above mechanism is fairly common. You put include guards around the body of the file, and define your commons there.. This is essentially what config.h ends up being with autoconf.. So nobody can say this isn't a standard mechanism for C code.

Just include common.h in any files that need it, done deal.

synthesizerpatel
  • 27,321
  • 5
  • 74
  • 91
  • I'm aware of the #idndef/#define/#endif structure, I've added more details to my question. – Huckle Mar 05 '12 at 21:14
  • 1
    It's still the same answer as what I've posted, note that your question _still_ lacks the important '#ifndef COMMON_INCLUDE_FILE\n #define COMMON_INCLUDE_FILE\n \n #endif\n'.. That specifically is the header guard that prevents your include from being pre-processed multiple times (and is the cause of your duplicate definition errors.. On a subsequent 'includes', if COMMON_INCLUDE_FILE is defined, it won't re-pre-process it. – synthesizerpatel Mar 06 '12 at 01:16
3

You should most definitely put your common macros in a single header for your entire project: code duplication is a dangerous thing that makes your maintenance costs go through the roof.

The warnings that you see may have to do with including the same header multiple times. You need to use include guards to avoid them.

EDIT (in response to the question update)

Your implementation of include guards is missing #define USEFULMACROS. It should be as follows:

//usefulmacros.h
#ifndef USEFULMACROS
#define USEFULMACROS
#define V4(str, ...) if(optv >= 4){printf("%s: "str,prog,__VA_ARGS__);}
#endif
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Good and precise answer, +1. But one thing to hint: *The warnings that you see may have to do with including the same header multiple times.* - The issue is not about including the same header file multiple times precisely; it is because the macro definition of `USEFULMACROS` is missing and thus the respective sub-macros of the non-existing `USEFULMACROS` attempt to get redefined on any later including of the header file of `usefulmacros.h`. – RobertS supports Monica Cellio Feb 06 '20 at 11:15
0

What you describe is the way to do it. What warning? If it's multiple definition you just want to protect the file as described in the answer to this: While using #ifndef, .h file being added multiple times

Community
  • 1
  • 1
Joe
  • 2,946
  • 18
  • 17
0

You check for USEFULMACROS macro definition with #ifndef but you didn't define it anywhere.

You have to add the line

#define USEFULMACROS

after

#ifndef USEFULMACROS
dAm2K
  • 9,923
  • 5
  • 44
  • 47