Предупреждение xc8: начальное значение для var отличается

Я столкнулся с предупреждением компилятора:

version.h:47: warning: (1478) initial value for "_svn_string_revision" differs to that in version.h:47

соответствующий файл version.h выглядит так:

#ifndef _VERSION_H_
#define _VERSION_H_

#define SVN_REVISION_NUMBER         31

const char *svn_string_revision      = "31"; // line 47

#endif //_VERSION_H_

Использование:

основной.с:

#include "version.h"
// I do not use svn_string_revision here.
// I only use SVN_REVISION_NUMBER
#pragma config IDLOC3=SVN_REVISION_NUMBER

другой файл.с:

#include "version.h"
// still no usage of svn_string_revision, only this:
EUSART_Write(SVN_REVISION_NUMBER);

Пока это описательно и ясно. Я предполагаю, что проблема в том, что строка const char определена в файле заголовка, который включается более чем в один файл исходного кода. Таким образом, компилятор видит более одной переменной «svn_string_revision» и обрабатывает ее как повторное объявление. Но обычно значение должно быть всегда одинаковым. Мой файл version.h представляет собой автоматически сгенерированный файл, который регенерируется перед каждой сборкой.

Кто-нибудь сталкивался с этим раньше, и как я могу справиться с этим? Чистым подходом было бы использование файла version.h, дополненного файлом version.c, где заголовок объявляет

extern const char *svn_string_revision;

и источник

const char *svn_string_revision = "31";

Но это потребовало бы от меня переписать автоматическую генерацию кода, чего я хотел бы избежать.

Короче, мои вопросы:

  • Правильно ли я понимаю предупреждение?
  • Как я могу изящно избежать этих предупреждений, учитывая, что я не хочу разбивать version.h на файлы .c и .h

person jwsc    schedule 04.12.2015    source источник


Ответы (1)


Первое решение:

static const char *svn_string_revision = "31";

Статическая переменная сделает переменную локальной для каждого файла C, поэтому конфликт не может возникнуть. Поскольку это константа только для чтения, все должно быть в порядке. Однако это означает, что в программе будет много копий переменной. Хороший компилятор может оптимизировать это, но, по моему опыту, я не уверен, что XC8 сделает это.

Второе решение, вероятно, лучше:

#define SVN_REVISION_NUMBER         31
#define STRINGIFY(s) #s
extern const char *svn_string_revision;

// in version.c
const char *svn_string_revision = STRINGIFY(SVN_REVISION_NUMBER);

Или просто :

#define SVN_REVISION_NUMBER         31
#define VERSION_STRING "31"
extern const char *svn_string_revision;

// in version.c
const char *svn_string_revision = VERSION_STRING;

Вы также можете просто удалить svn_string_revision и использовать вместо него VERSION_STRING, но вы должны проверить перед этим, что XC8 не создает много копий строки.

person ElderBug    schedule 04.12.2015
comment
Эй, спасибо за хорошие решения. Добавление версии version.c создает некоторые неудобства, но это лучше, чем постоянное копирование строки ревизии. - person jwsc; 07.12.2015
comment
@jwsc Вероятно, стоит попробовать встроенные версии (статические и макросы) и проверить, увеличивается ли размер исполняемого файла, когда вы используете его больше. Если он не растет, значит, он правильно оптимизирован. Версия макроса (с использованием 31 непосредственно в макросе), скорее всего, будет оптимизирована, IMO. - person ElderBug; 07.12.2015
comment
xc8 и оптимизация? Это было хорошо ;-) Я рад, если он пишет почти безглючную сборку. - person jwsc; 07.12.2015
comment
@jwsc Я не пробовал полную версию, но в бесплатной версии -O1 действительно не хватает некоторых оптимизаций: S - person ElderBug; 07.12.2015