cppcheck - スタイルの意味 - bzeroCalled ~ noExplicitConstructor

 
bzeroCalled
clarifyCondition
copyCtorPointerCopying
duplicateBranch
duplicateBreak
duplicateExpression
knownConditionTrueFalse
noConstructor
noCopyConstructor
noExplicitConstructor
noOperatorEq

bzeroCalled

ID:bzeroCalled
Obsolescent function 'bzero' called. It is recommended to use 'memset' instead..
 これは簡単。  bzero は非推奨なのです。  いずれなくなる運命にある関数なので、可能であれば memset に置き換えていきましょう。

clarifyCondition

ID:clarifyCondition
Boolean result is used in bitwise operation. Clarify expression with parentheses.
 実は、これ、よくわからんのです。  CLI で

array<byte>^ arrayVal = static_cast<array<byte>^>(value);
 という (value は変数で上位からの呼び出し時に決められます) 記述をしていると出力されました。  どこか問題なのだろうか?

copyCtorPointerCopying

ID:copyCtorPointerCopying
Value of pointer 'pread', which points to allocated memory, is copied in copy constructor instead of allocating new memory.
 これは
#include <limits.h>
#include <stdio.h>

class Sample
{
public:
	Sample(const char *aname);
	Sample::Sample(const Sample& other);
	virtual ~Sample(void);

	Sample &operator=(const Sample &other)
	{
		if (this != &other)
		{
			pread = other.pread;
		}

		return *this;
	}

private:
	FILE *pread;								// ファイル
};

Sample::Sample(const Sample& other)
{
	this->pread = other.pread;
}

Sample::Sample(const char *aname)
{
	char  afile[PATH_MAX];						// ファイル名

	sprintf(afile, "%s.c", aname);

	if ((pread = fopen(afile, "r")) == NULL)
	{
		perror(afile);
		return;
	}
}

Sample::~Sample(void)
{
	fclose(pread);
}

 というソースで指摘されます。  27行目がいかんのですね。人様の使っているポインタを自分のものにしようとしているのだからまずいですね。

duplicateBranch

ID:duplicateBranch
Found duplicate branches for 'if' and 'else'.

	if (a == 0)
	{
		b = 0;
	}
	else
	{
		b = 0;
	}
 のように if と else でまったく同じ処理を記述していると出力されます。  実際のケースでは、複雑な事情があったんですけど・・・。ここではその説明は割愛します。

duplicateBreak

ID:duplicateBreak
Consecutive return, break, continue, goto or throw statements are unnecessary.
void sub(int a)
{
	int b = 0;

	switch(a)
	{
	case 0:
		if (b == 0)
		{
			return;
			break;
		}

		break;

	case 1:
		break;

	default:
		break;
	}
}

 ってなときに出力されます。  11行目の break は不要ですと言っているわけです。。  「スタイル」というレベルの微妙なとこなんですけど。  わたしはこれはそのままにします。  何らかの対応で 13行目の箇所に処理が入ることがありえるからです。

duplicateExpression

ID:duplicateExpression
Same expression on both sides of '-'.

#include <stdio.h>

int main(int argc, char* argv[])
{
	int a[10] = {};

	・・・

	a[1-1] = 0;
	a[2-1] = 0;

	・・・

	return 0;
}
 てなコードを書いて出力されました。  9行目ですね。1 - 1 は 0 に決まってんじゃん。てなことでしょうか。  算数の基本ですね。A - A = 0 なので、引き算する意味がないでしょってことです。  実際は、意図的にやっていることなので無視しました。

knownConditionTrueFalse

ID:knownConditionTrueFalse
Condition '式' is always true
 下記のようなコーディングで出力されます。

void hoge(int* n1)
{
	int n2 = 0;

	if (n2 == 0)
	{
		n1 = NULL;
	}
}
 実際のソースがこんなに短けりゃ、すぐにわかるってもんですが・・・。  3行目で初期化した後になんの変更もないまま比較しているので 5行目は「常に真ですよ」ってことです。

noConstructor

ID:noConstructor
The class 'クラス名' does not have a constructor.
 「クラスにコンストラクタが存在しない」と言っているようです。  これが出力されたソースでは、実際にはコンストラクタは存在しているのです。  C/C++ でなく CLI のソースで「public ref class クラス名'」というクラス定義であることが原因なのか?  よくわかっていません。

noCopyConstructor

ID:noCopyConstructor
Class 'クラス名' does not have a copy constructor which is recommended since it has dynamic memory/resource allocation(s).
#include <limits.h>
#include <stdio.h>

class Sample
{
public:
	Sample(const char *aname);
	virtual ~Sample(void);

private:
	FILE *pread;								// ファイル
};

Sample::Sample(const char *aname)
{
	char  afile[PATH_MAX];						// ファイル名

	sprintf(afile, "%s.c", aname);

	if ((pread = fopen(afile, "r")) == NULL)
	{
		perror(afile);
		return;
	}
}

Sample::~Sample(void)
{
	fclose(pread);
}

 上記のソースの 20行目でチェックにかかります。  ん~よくわからないのです。「コピーコンストラクタを持っていないのに動的なリソースを持ってんじゃん」って言っているようには見えるのですが・・・。  よくわからないままに、コピーコンストラクタだか、operator= だかをいれてやってこんなソースにするとメッセージは出力されなくなるんですがね。
#include <limits.h>
#include <stdio.h>

class Sample
{
public:
	Sample(const char *aname);
	Sample::Sample(const Sample& other);
	virtual ~Sample(void);

	Sample &operator=(const Sample &other)
	{
		if (this != &other)
		{
			pread = other.pread;
		}

		return *this;
	}

private:
	FILE *pread;								// ファイル
};

Sample::Sample(const Sample& other)
{
	this->pread = other.pread;
}

Sample::Sample(const char *aname)
{
	char  afile[PATH_MAX];						// ファイル名

	sprintf(afile, "%s.c", aname);

	if ((pread = fopen(afile, "r")) == NULL)
	{
		perror(afile);
		return;
	}
}

Sample::~Sample(void)
{
	fclose(pread);
}

 今度はこっちの 27行目が「copyCtorPointerCopying」ってのになっちゃうんだな。

noExplicitConstructor

 これは、バージョン 1.81 では、警告だったはずなのですが 1.85 ではスタイルになっちゃってます。
ID:noExplicitConstructor
Class 'クラス名' has a constructor with 1 argument that is not explicit. Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.
#include <limits.h>
#include <stdio.h>

class Sample
{
public:
	Sample(const int a);
	virtual ~Sample(void);

private:
	int a_;
};

Sample::Sample(const int a)
{
	a_ = a;
}

Sample::~Sample(void)
{
}

 7行目があかんと言われます。  これが、実はよくわかっていないのですが、警告の発生したクラスは、引数のあるコンストラクタが存在します。これが not explicit 明確に定義されていない?  宣言はあるのですが・・・。  とりあえず、無視しちゃっています。

noOperatorEq

ID:noOperatorEq
Class 'Sample' does not have a operator= which is recommended since it has dynamic memory/resource allocation(s).
 「noCopyConstructor」と同じソースで出現しました。
#include <limits.h>
#include <stdio.h>

class Sample
{
public:
	Sample(const char *aname);
	virtual ~Sample(void);

private:
	FILE *pread;								// ファイル
};

Sample::Sample(const char *aname)
{
	char  afile[PATH_MAX];						// ファイル名

	sprintf(afile, "%s.c", aname);

	if ((pread = fopen(afile, "r")) == NULL)
	{
		perror(afile);
		return;
	}
}

Sample::~Sample(void)
{
	fclose(pread);
}

 「operator=」がないっちゅうんでしょうなぁ。  これも「noCopyConstructor」と同じ手当で一応、消えます。