Frage

I am currently looking through the code written by senior engineer. The code works fine but i am trying to figure out one detail.

He uses quite a few global variables and his code is broken down into a lot of separate files. So he uses a technique to make sure that global vars are declared everywhere where he needs to access them but are only defined once.

The technique is new to me but I read few articles on the internet and got some understanding about how it works. He uses

#undef EXTERN

followed by conditional definition of EXTERN as an empty string or actual extern. There is a very good article here explaining how it works. Also there is a discussion here

What gets me confused is that all examples I saw on the web suggest to include header file in a regular way in all of the source files that need it except for one. In this single special case line that includes header is preceded by definition of a symbol that will ensure that EXTERN will be defined to an empty string and .. so on (see link above). Typically this single special case is in main or in a separate source file dedicated to the declaration of global variables.

However in the code that I am looking at this special case is always in the source file that corresponds the header. Here is the minimal example:

"peripheral1.h" :

#undef EXTERN
#ifndef PERIPHERAL_1_CPP
#define EXTERN extern
#else
#define EXTERN
#endif

EXTERN void function1(void);

"peripheral1.cpp" :

#define PERIPHERAL_1_CPP
#include "peripheral1.h"

function1()
{
    //function code code here
}

Everywhere else in the code he just does

#include "peripheral1.h"

My question is how and why does that work? In other words, how does compiler know where to define and where to just declare function (or variable, or class ...)? And why is it ok in above example to have the lines :

#define PERIPHERAL_1_CPP
#include "peripheral1.h"

in actual peripheral1.cpp rather then in main.cpp or elsewhere?

Or am I missing something obvious here?

War es hilfreich?

Lösung 2

Nostalgia

Ahh, this takes me back a fair way (about 20 years or so).

This is a way for C code to define global variables across multiple files: you define the variable once using a macro to ensure it is defined exactly only once, and then extern it in other C code files so you can utilise it. Nowadays it is quite superfluous in many instances, however it still has its place in legacy code, and will (most likely) still work in many modern compilers, nut it is C code not C++.

Normally the likes of #define PERIPHERAL_1_CPP is utilised to ensure uniquenesss of inclusion like a #pragma once

In my own code I would use something like:

#ifndef PERIPHERAL_1_CPP
#define PERIPHERAL_1_CPP
// my includes here
// my code here
#endif

That way you can #include the file as many times as you want all over your code, in every code file even, and you will avoid multiple definition errors. To be fair I normally do it with the .h files and have something like:

// for absolutely insane safety/paranoia
#pragma once
// normally sufficient
#ifndef PERIPHERAL_1_H
#define PERIPHERAL_1_H
// my includes here
// my code here
#endif

I have never tried it on cpp files but wil llater tonight to see if there is any benefit one way or the other:)

Give me a shout if you need any more info:)

Andere Tipps

All the source files, except "perripheral1.cpp", after preprocessing contain a sequence of external variable declarations like:

extern int a;
extern int b;
extern int c;

In peripheral1.cpp only, after preprocessing, there will be a sequence of declarations:

int a;
int b;
int c;
int d;

which are tentative definitions of the corresponding variables, which, under normal circumstances are equivalent of the external definitions :

int a = 0;
int b = 0;
int c = 0;
int d = 0;

End result is, variable are declared everywhere, but defined only once.

PS. To be perfectly clear ...

In other words, how does compiler know where to define and where to just declare function (or variable, or class ...)?

The compiler knows where to declare, whenever it encounters a grammatical construct, which is defined in the standard to have the semantics of a declaration. The compiler knows where to define, whenever it encounters a grammatical construct, which is defined in the standard to have the semantics of a definition.

In other other words, the compiler does not know - you tell it explicitly what you want it to do.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top