1

私は次のC++コードを持っており、コード上でPClintを実行しています。

質問1:

#if !WIN32
#define ULONG_MAX 0xffffffff
#endif

上記のコードは次のようにlintエラーをスローしています

エラー26:式が必要です。「WIN32」が見つかりました。
エラー30:整数定数が必要です。

上記のエラーを修正するにはどうすればよいですか?

質問2:

const char CompanyName[] = "mycompany"; 

エラー:注960:MISRA必須ルール8.5に違反し、ヘッダーファイルにオブジェクト/関数の定義がありません

上記のエラーを修正するにはどうすればよいですか?

質問3:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

Note 960:MISRA必須ルール10.1に違反し、暗黙的な変換により符号が変更されます

上記のエラーを修正するにはどうすればよいですか?

4

6 に答える 6

4

初め:

代わりにこれを行う必要があります:

#ifndef WIN32
#define ULONG_MAX 0xffffffff
#endif

2番:

ヘッダーファイルでそれを定義することはできません。そうしないと、同じシンボルが複数のコンパイル単位に表示されます。

代わりに行う必要があるのは、ヘッダーで宣言することだけです。

extern const char CompanyName[];

そして、モジュールの1つで一度定義します。

const char CompanyName[] = "mycompany"; 

第3:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

これは珍しいことですが、それ0は符号付き定数のようです。そして、それに割り当てるとunsigned long、暗黙の型キャストがあります。ほとんどのコンパイラは、実際にはこれに対して警告しません。

于 2011-11-10T08:15:10.853 に答える
2

いくつかの点を明確にする必要があります。たとえば、次の行です。

#if !WIN32

/DWIN32=1は実際には標準によって明確に定義されており、コンパイラの呼び出しに常にまたはが含まれている場合は、合理的に使用できます-DWIN32=0。さらに言えば、標準では、定義されていないシンボルはマクロ展開中に置き換えられるとされているため、他の規則でシンボルはWindowsマシンでのみ定義されると規定されていない限り0、行に問題はありませんが、値は指定されていないように定義されています。その場合、次のようなものが必要です。

#ifndef WIN32

結局、それはコンパイラの依存関係を処理するために確立した規則に依存します。

一方、直後の行はULONG_MAX、CおよびC ++標準で定義されている記号()を定義しているため、避ける必要があります。ここでの3行のシーケンスは、次のように置き換える必要があります。

#include <limits.h>

2番目の質問に関しては、エラーがMISRAルールの誤解ではないかどうかはわかりません。C ++では、constデフォルトで内部リンケージを意味します。ヘッダーでこのようにシンボルを定義すると、変数の複数のインスタンス化が発生します(各変換単位で異なるアドレスを使用)が、複数の定義で問題は発生しません。また、代替案にも欠点があります。ここでの私の好みは、変数定義をマクロに置き換えることです。

#define CompanyName "mycompany"

しかし、マクロには独自の問題があります。シンボルexternを宣言し、それを1つの(そして1つだけの)ソースファイルで定義することも別の方法ですが、これには2つの異なるファイルでの2つのステートメントが含まれ、(変数が果たす役割に応じて)1つが望ましい場合があります。(名前から判断すると、2つのステートメントが問題になることはないと思いますが、ヘッダーにテキストを表示したままにしておくことが望ましい場合もあります。)書いたままにしておくことも実行可能です。あなたの会社がそれに対して厳格な規則を持っていない限り、代替案。

最後の点に関しては、式は符号付きの0タイプを持っています。intタイプを明確に指定できます0ULが、率直に言って、これは必須ではありません。0タイプ0に関係なく、タイプを強制したい場合もありますが、算術演算が特定の方法で行われるようにするために、これはそれらの1つではありません。エラー/警告に関しては、これもMISRAルールの誤解であると思われます。符号を変更する暗黙の変換は問題になる可能性がありますが、変換されるものが非常に小さい非負の定数整数である場合は問題になりません。だから書く0UL会社の規則を順守する必要があるが、これが愚かなことをしていることを理解してください。基本的に健全な規則が関連性のない場合に適用される場合です。

于 2011-11-10T08:37:05.783 に答える
1

最初の質問については、あなたが使うべきだと思います

#ifndef WIN32

それ以外の

#if !WIN32

WIN32マクロは常に存在するとは限らないため、「偽」ではなく、その存在を確認する必要があります。

于 2011-11-10T08:16:19.593 に答える
0

質問2の場合、その行はヘッダーファイル内にありますか?一般に、ヘッダーに変数を定義しないでください。特に、そのヘッダーが複数のファイルに含まれている場合は、同じ変数の2つのコピーが作成され、リンクエラーが発生します。

于 2011-11-10T08:15:52.207 に答える
0

もありますが#if !defined(WIN32)#ifndef WIN32わかりやすいです。

于 2011-11-10T08:30:26.837 に答える
0

これらの報告されたエラーはいずれもC++エラーではありません。それらはスタイルの問題です。

初め:

#if !WIN32
#define ULONG_MAX 0xffffffff
#endif

これは合法です。ディレクティブでは、#if定義されていないトークンはすべて。に置き換えられ0ます。#ifndef WIN32しかし、他の人がすでに示唆しているように、おそらく書く方が良いスタイルです。

しかし、実際には、そのすべてがおそらく悪い考えです。 は、C標準ヘッダーおよびC++標準ヘッダーでULONG_MAX定義されたマクロです。上記の3行を次のように置き換えます。<limits.h><climits>

#include <climits>

2番:

const char CompanyName[] = "mycompany";

合法ですが、悪い考えです。ヘッダーファイルが#include異なる翻訳単位からのdである場合、の複数の定義がありCompanyNameます。(C ++ルールがそれについて何を言っているのかよくわかりません。)Mysticialの答えを参照してください。

第3:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

ここでPC-lintは過度にうるさいです。0はい、 (タイプのint)を暗黙的に変換unsigned longすると符号が変更されますが、この場合、問題が発生する可能性はありません。ただし、unsigned long型のリテラルを使用すると、警告を回避できます。

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0UL;
于 2011-11-10T08:36:02.007 に答える