0

コンパイラの警告が表示されました:

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_

使用法:

main.c:

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

otherfile.c:

#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.c で補完された version.h ファイルを使用することです。ここで、ヘッダーは次のように宣言します。

extern const char *svn_string_revision;

とソース

const char *svn_string_revision = "31";

しかし、これには自動コード生成を書き直す必要があり、これは避けたいと思います。

簡単に言えば、私の質問は次のとおりです。

  • 警告に対する私の理解は正しいですか?
  • version.h を .c と .h ファイルに分割したくない場合、これらの警告を適切に回避するにはどうすればよいですか
4

1 に答える 1

2

最初の解決策:

static const char *svn_string_revision = "31";

static は変数を各 C ファイルに対してローカルにするため、競合は発生しません。これは読み取り専用の定数なので、問題ないはずです。ただし、これは、プログラム内に変数のコピーが多数存在することを意味します。優れたコンパイラはこれを最適化できますが、私の経験では、XC8 がそれを行うかどうかはわかりません。

2番目の解決策、おそらくより良い:

#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 が文字列の多くのコピーを作成しないことを事前に確認する必要があります。

于 2015-12-04T14:12:46.800 に答える