-1

How do I define a macro in C so that I can use the "extern" keyword on the first pass in a header file, then on subsequent passes initialize the constant variables? I'm using Visual Studio 2022 on a Windows 10 computer.

At the moment I have something like the following in my header file "images.h"

#pragma once

#include <stdio.h>
// Other #includes

typedef const unsigned char CBYTE;
typedef const int CINT;
// Other typedefs

#include "globals.h"
// Rest of the "images.h" header file.

Then in my "globals.h" file I have the following code:

#ifndef _GLOBALS_H_
#define _GLOBALS_H_

extern CBYTE gc_eod16;
extern CINT gc_stf;

#else

CBYTE gc_eod16 = 127;
CINT gc_stf = 2;

#endif

Then in the file "images.c" with the main function I have something like this:

#include "images.h"
#include "globals.h"

int main(void) {

    // Code in main

    return 0;
}

As I have several source files which are compiled together I need to use the "extern" keyword, and have #include "images.h" at the top of the other files.

Rather than initializing the global constants separately in the file with the main function, I wanted to put them with "extern" and initialization them in the "globals.h" file. This appears to compile OK, but it's untidy to repeat the global constants in the "globals.h" file.

My question is, is there a macro so that when "globals.h" is included for the first time, the statements:

extern CBYTE gc_eod16;
extern CINT gc_stf;

are generated, then on the next #include these are replaced by:

CBYTE gc_eod16 = 127;
CINT gc_stf = 2;

so that in the source code there is one line for each variable, i.e on the first #include "extern" is placed before the variable type and name, then on the second #include "extern" is omitted, and following the variable the string "= 127; etc. is appended?

How is this done? I would be most grateful to know.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
csharp
  • 464
  • 2
  • 10
  • 19
  • 1
    You can't make a macro that works differently on each pass, but you can delete the macro and define it differently. See `#undef`. – Mark Ransom Apr 23 '22 at 03:40
  • Header files should be idempotent. It shouldn't matter how many times you include them, or in what order. – user3386109 Apr 23 '22 at 03:59
  • @user3386109 — with a very few exceptions, like ``… – Jonathan Leffler Apr 23 '22 at 04:24
  • You can find a discussion of alternative ways on how to do this in [How do I use `extern` to share variables between source files?](https://stackoverflow.com/q/1433204/15168), particularly near the end (of a rather long answer). – Jonathan Leffler Apr 23 '22 at 04:26

1 Answers1

1

No.

You want the pre-processor to remember things between compilation units. Than cannot be done.

Just be a good neighbor and initialize the variables in their own .cpp file.

Now, if you still want to do things the hard way, you may want to do something similar to what it's done in windows when compiling and using DLLs.

// globals.h

#ifndef BUILDING_GLOBALS
  extern CBYTE gc_eod16;
  extern CINT gc_stf;
#else
  CBYTE gc_eod16 = 127;
  CINT gc_stf = 2;
#endif

Then, you will have to modify only one .cpp file to look like this:

#define BUILDING_GLOBALS
#include "globals.h"

It behaves like this:

  • Every file that doesn't define BUILDING_GLOBALS will see the extern thing.
  • Only one file will define BUILDING_GLOBALS, and that file will see the initialization.
ichramm
  • 6,437
  • 19
  • 30
  • OK, many thanks to JuanR, and this works without any errors. I just replaced #ifndef _GLOBALS_H_ and #define _GLOBALS_H_ at the top of "globals.h" by #ifndef BUILDING_GLOBALS. In the main header file "images.h" I still have #include "globals.h", and added #define BUILDING_GLOBALS before #include "globals.h" in "images.c" which contains the main function and defines the global variables. All the "*.c" files have #include "images.h" at the top so they all know about the global variable. The link on how to use "extern" by Jonathan Leffler is also very useful. – csharp Apr 23 '22 at 18:59
  • great! please mark the answer as accepted for completion. – ichramm Apr 23 '22 at 23:43