jpmorr
jpmorr

Reputation: 636

Making a typedef struct externally available in c++

I think I'm doing something stupid, but I don't quite know what. I'm trying to rewrite a fairly simple library I have that is reading in some variables from a text file and then shares them with some other source files for use elsewhere. When I wanted to pass a double I was doing this:

#if !defined(SharedVariables_h)
#define SharedVariables_h

#include <vector>

extern double coeff_A;

#endif

and then doing this in both the source file where it was defined and the other source files where I want to use it:

#include "SharedVariables.h"

to make coeff_A available in the new source file.

But then my model got more complicated and I was using more coefficients so I decided to store them in a structure and pass that structure using extern instead. I created a new header file for the structure (CParameters.h):

#pragma once
#if !defined(CParameters_h)
#define CParameters_h

typedef struct
{
    int         coeff_A;
    int         coeff_B;
    double      coeff_C;
    double      coeff_D;

} SGlobalParameterData;


#endif

and then defined the struct like this:

#if !defined(SharedVariables_h)
#define SharedVariables_h

#include "CParameters.h"
#include <vector>

extern SGlobalParameterData globalParameters;

#endif

In the first source file where I read in all the values from the data files and using the values I've replaced:

#include "SharedVariables.h"


double coeff_A;
...

with

#include "SharedVariables.h"


SGlobalParameterData globalParameters;

globalParameters = readProperties(prefsFile);

....

In the second source file which also needs to use some of these variables I've added #include "SharedVariables.h" and then the IDE and compiler let me easily access globalParameters.coeff_A, globalParameters.coeff_B, etc.

I thought this should work and everything compiles without any errors, but it's not actually passing the values read into globalParameters to the second source file. Everything is just zero when I'm debugging the code.

So there are really two questions: 1) Is it possible to share structs using extern like for double, and 2) if it is, what have I done wrong.

Hopefully someone can point out my mistake.

Edit

I've added in an line of code in my example to show the function that assigns the values to the struct. This is working and the values read from the prefsFile are available and correct in the f1rst source file, but these values are not passed to source file 2. I'm going to do some more testing because it appears I may have made some other mistake elsewhere.

Upvotes: 0

Views: 599

Answers (2)

eerorika
eerorika

Reputation: 238351

  1. Is it possible to share structs using extern like for double

Yes.

  1. if it is, what have I done wrong.

Something that you haven't shown to us.

Everything is just zero

This is to be expected because variables with static storage are zero-initialised, and you never modify globalParameters in the example.

Here is your code running. Only change I made was to add some output, and actually set some other value than zero. That non-zero value works as expected: https://wandbox.org/permlink/CasO8c68W3FmBsQH

Upvotes: 0

rustyx
rustyx

Reputation: 85361

Your confusion stems from the use of typedef and mixing of declarations and definitions.

In C++ typedef isn't needed to define a struct type and is only confusing.

typedef struct { ... } SGlobalParameterData; - this declares a type SGlobalParameterData that is a struct. It defines no instance of the struct.

struct SGlobalParameterData { ... }; - same thing, declares a type SGlobalParameterData that is a struct.

struct { ... } globalParameterData; - this defines an object globalParameterData of an unnamed struct type.

struct SGlobalParameterData { ... } globalParameters; - this defines an object globalParameters of an struct type called SGlobalParameterData.

So... the following might be most readable/clean IMHO:

In the header:

struct SGlobalParameterData   // type declaration
{
    int         coeff_A;
    int         coeff_B;
    double      coeff_C;
    double      coeff_D;
};

extern SGlobalParameterData globalParameters; // global instance *declaration*

In one of source files:

#include "the header above"

SGlobalParameterData globalParameters; // global instance *definition*

In other source files:

#include "the header above"

// globalParameters is already visible and usable

Of course you have to compile all source files and link them together into an executable.

Upvotes: 3

Related Questions