C struct - легальные участники? - PullRequest
       18

C struct - легальные участники?

0 голосов
/ 11 сентября 2009

Это законно и / или хорошая практика?

#define SOFTWARE_VERSION_NUMBER  "7.0v1.1" 

Хотите, чтобы структура всегда содержала номер версии.

typedef struct {
    char SOFTWARE_VERSION_NUMBER; 
    int a;
    int b;
    int c;
}mystruct;

Ответы [ 7 ]

3 голосов
/ 11 сентября 2009

Нет, это не законно C.

Лучший способ сделать это - создать функцию для генерации новых экземпляров вашей структуры и поместить туда присваивание:

#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;
}
2 голосов
/ 11 сентября 2009

Назовите меня сумасшедшим, но как разработчик, который рубит зубы на встроенных системах с объемом памяти менее чем 640K , я сжимаюсь каждый раз, когда вижу #define строку Без изменения настроек по умолчанию компилятор может создавать новый экземпляр строки & mdash; и потенциально выделять память для этого нового экземпляра & mdash; каждый раз, когда вы используете макрос.

Альтернатива, которая выделяет строку только один раз:

const char * const MyVersion = "7.0v1.1"  // Const ptr to const string

typedef struct _foo_t {
   const char *ver;
   int a;
   int b;
   int c;
} foo_t;

foo_t bar = { MyVersion, 1, 2, 3 };  // Copy the ptr, not the string
2 голосов
/ 11 сентября 2009

Нет, это не законно.

Вы можете, однако, сделать:

#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};
2 голосов
/ 11 сентября 2009

Ваш строковый макрос не может быть сохранен в одном символе. Вам потребуется буфер char * или char [strlen (SOFTWARE_VERSION_NUMBER)].

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

mystruct_t ms;
strcpy(ms.version, SOFTWARE_VERSION_NUMBER);
1 голос
/ 12 сентября 2009

Вот один подход, который исправляет все во время компиляции:

/* -------------------------------------------------- */
/* 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;

Если необходимо изменить номер версии, необходимо отредактировать только Version.h (при условии, что строка версии больше не получается).

На константу Global_SoftwareVersion можно последовательно ссылаться в коде.

1 голос
/ 11 сентября 2009

Могу я спросить, почему вы хотите сохранить это в структуре? Это отправляется через сеть?

Что касается хранилища, компиляторы (или компоновщики, я не уверен) могут хранить одну и ту же строку в одном месте в разделе данных, если одна и та же точная строка используется более одного раза, поэтому использование макроса не плохо вещь. Лично я бы сделал что-то вроде этого:

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

Если это для плагина-подобной архитектуры DLL, версия функции является наиболее подходящей (например, следующая:

const char *pluginVer = dll->GetSoftwareVersion(); // where GetSoftwareVersion is of type:
typedef const char *(* GetSoftwareVersionProc)(void);
1 голос
/ 11 сентября 2009

Не законно, как напечатано.

Если вы хотите сохранить номер версии, я рекомендую кодировать его в 32-битное целое и заполнять его во время выделения структуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...