views:

145

answers:

7

Is this legal and/or good practice?

#define SOFTWARE_VERSION_NUMBER  "7.0v1.1"

Want struct to always contain the version number.

typedef struct {
    char SOFTWARE_VERSION_NUMBER; 
    int a;
    int b;
    int c;
}mystruct;
+1  A: 

Not legal as typed.

If you want to store a version number I recommend encoding it into a 32 bit int and filling it in at struct allocation time.

Dan Olson
+2  A: 

Your string macro cannot be stored in a single char. You would need a char * or char[strlen(SOFTWARE_VERSION_NUMBER)] buffer.

typedef struct _mystruct_t
{
    char version[10];
    int etc;
} mystruct_t;

mystruct_t ms;
strcpy(ms.version, SOFTWARE_VERSION_NUMBER);
Nick Bedford
+3  A: 

No, that's not legal C.

The best way to do this is to create a function to generate new instances of your struct, and put the assignment in there:

#define SOFTWARE_VERSION_NUMBER  "7.0v1.1"

typedef struct {
    char ver[sizeof SOFTWARE_VERSION_NUMBER]; 
    int a;
    int b;
    int c;
} mystruct;

mystruct *mystruct_new(int a, int b, int c)
{
    mystruct *ms = malloc(sizeof *ms);

    if (ms)
    {
        strcpy(ms->ver, SOFTWARE_VERSION_NUMBER);
        ms->a = a;
        ms->b = b;
        ms->c = c;
    }

    return ms;
}
caf
OK thanks, my intention was to not assign it like the rest of the members .....somehow make it a constant in the structure, only changed at the macro...
Tommy
+2  A: 

No, it's not legal.

You could, however, do:

#define SW_VERSION "1.01"
typedef struct _foo {
 char ver[sizeof SW_VERSION];
 int a;
 int b;
 int c;
} foo;

foo bar={SW_VERSION,1,2,3};
Coleman
does not compile
Tommy
you're right, fixed in edit.
Coleman
As Adam points out below, the best way to do this is with a const char*, but I was just using the OP's code. So, if you're going to implement this, use const char*, not a #define.
Coleman
+1  A: 
Adam Liss
+1  A: 

Might I ask why you want to store this in a struct? Is it being sent across a network?

As far storage goes, compilers (or linkers, I'm not sure) can store the same string in one place in the data section if the same exact string is used more than once so using the macro isn't a bad thing. Personally I would do something like this:

const char *GetSoftwareVersion (void)
{
    return "Version 7.0.1";
}

If it is for a plugin-like DLL architecture, the function version is the most appopriate (such as the following:

const char *pluginVer = dll->GetSoftwareVersion(); // where GetSoftwareVersion is of type:
typedef const char *(* GetSoftwareVersionProc)(void);
Nick Bedford
+1  A: 

Here's one approach, which fixes everything at compile time:

/* -------------------------------------------------- */
/* Version.h */
#define SOFTWARE_VERSION_NUMBER "7.0v1.1"

/* -------------------------------------------------- */
/* Global.h */
#define SoftwareVersionLENGTH   8
extern const char Global_SoftwareVersion[SoftwareVersionLENGTH];

/* -------------------------------------------------- */
/* Global.c */
#include "Global.h"
#include "Version.h"
const char Global_SoftwareVersion[SoftwareVersionLENGTH]
    = SOFTWARE_VERSION_NUMBER;

If the version number needs to be changed, only Version.h must be edited (assuming the version string doesn't get any longer).

The constant string Global_SoftwareVersion can then be referenced, consistently, in the code.

Steve Melnikoff