PVS-Studio 6.00新年リリース:Roslynの確認

PVS-Studio 6.00、C、C ++、C#
待望のイベントが到着しました。 C#プロジェクトのチェックをサポートするPVS-Studio 6.00静的コードアナライザーのリリースバージョンをリリースしました。 現在、コードはC、C ++、C ++ / CLI、C ++ / CX、C#の言語で記述されています。 アナライザーの6番目のバージョンのリリースでは、オープンRoslynプロジェクトの検証のタイミングを調整しました。 C#サポートがPVS-Studioアナライザーに登場したのはRoslynのおかげであり、このプロジェクトの実装と開発についてMicrosoftに非常に感謝しています。

PVS-Studio 6.00


PVS-Studioは、コードの作成段階での使いやすさとエラーの検索に重点を置いた静的コードアナライザーです。

C / C ++プログラムの新しいタイプのエラーを検索するための診断ルールを常に追加しています。 たとえば、コンストラクタで初期化されていないクラスメンバーの検索を最近追加しましたが、これは非常に難しいタスクでした。 ただし、診断の改善は、古いバージョンを変更する理由ではありません。 そして、本当に新しいものがアナライザーに追加されるのを待ちました。 そして、そのような瞬間が来ました。 C#言語をサポートするアナライザーの6番目のバージョンを世界に紹介します。

PVS-Studio 6.00の試用版は次から入手できます。

http://www.viva64.com/en/pvs-studio-download/

アナライザーの6番目のバージョンでは、Visual Studioの古いバージョンのサポートを拒否しました。 現在、VS2005およびVS2008はサポートされていません。 チームが引き続きこれらのバージョンのVisual Studioを使用している場合は、以前のバージョン5.31またはそのアップグレード(存在する場合)を引き続き使用することをお勧めします。

デモ版には次の制限があります。 50回のコードジャンプを実行できます。 その後、アナライザーはユーザーに自分自身に関する情報を送信するように指示します。 彼が同意すれば、彼にはさらに50回の移行が与えられます。

デモの制限は厳しいように思えるかもしれません。 しかし、彼には正当な理由があり、多くの実験の後に彼に来ました。

少数の「クリック」は、メールでの通信をより早く開始するのに役立ちます。 誰かが他のメッセージを見たい場合は、たとえば1週間、登録キーを渡す準備ができています。 彼は私たちに手紙を書くだけで十分です。 原則として、通信の過程で、私たちは人々が迅速にナビゲートできるよう支援し、アナライザーを使用することでどのように素早く簡単に利益を得ることができるかを支援します。

ロズリン


プログラマーは広告の影響を受けません。 「ミッション」、「非の打ちどころのない」、「イノベーションに焦点を当てる」という言葉で彼らを忘れることはできません。 プログラマは広告を読まず、Adblock Plusを使用してバナーを無効にする方法を知っています。

持ちこたえることができるのは、このツールまたはそのツールがどのように役立つかを示すことだけです。 このようなパスを選択し、開いているプロジェクトをチェックすることで静的解析ツールがどのように役立つかを示しました。

PVS-Studioは、CoreCLR、LibreOffice、Linux Kernel、Qt、Unreal Engine 4、Chromiumなどの有名なプロジェクトでエラーを見つけることができます。 現時点で、私たちのチームは230の開いているプロジェクトをチェックし、それらに9355個のエラーが見つかりました。 はい、はい9355はエラーの数であり、診断メッセージの数ではありません。 最も興味深いチェックは関連記事で見つけることができます。

これで、C#プロジェクトをチェックする番になりました。 当然のことながら、最初の実証済みプロジェクトの1つはRoslynでした。 最終的に、この特定のプロジェクトのおかげで、PVS-StudioでC#コードの分析をサポートすることが可能になりました。

このオープンソースプロジェクトを作成してくれたMicrosoftに感謝します。 C#インフラストラクチャの開発に大きな影響を与えます。 はい、彼はすでに影響を与えています! たとえば、ReSharperやCodeRushなどの有名なプロジェクトは、Rolsynベースに転送されます。

Roslynプロジェクト自体について少し説明します。

コード名Roslynでよく知られている.NETコンパイラプラットフォームは、C#およびVisual Basic .NETのソースコードを分析するためのオープンソースコンパイラとAPIのセットです。 プラットフォームはMicrosoftによって開発されています。

このプラットフォームには、C#およびVB.NET用の自己完結型コンパイラが含まれています。 これらは、従来のコマンドラインアプリケーションとしてだけでなく、.NETコードからアクセスできるネイティブAPIとしても利用できます。 Roslynは、構文解析(語彙)コード分析、セマンティック分析、CILバイトコードの動的コンパイル、およびアセンブリ生成のためのモジュールへのアクセスを提供します。 Roslynが提供するAPIは、機能API(機能API)、ワークスペースAPI(ワークスペースAPI)、コンパイラAPI(コンパイラAPI)の3つのタイプに分類できます。 機能的なAPIは、リファクタリングとデバッグを容易にします。 プラグイン開発者は、ワークスペースAPIを使用して、Visual StudioなどのIDEに固有の特定のメカニズムを実装できます。たとえば、変数と値の間の一致の検索やコードの書式設定などです。 コンパイラAPIは、識別子と値のバインディングの段階で構文ツリー分析および制御フロー分析モジュールへの直接呼び出しに関する情報を提供することにより、さらに高度なソースコード分析の機会を提供します。

追加リンク:
  1. Github ロズリン
  2. ウィキペディア .NETコンパイラプラットフォーム(「Roslyn」)
  3. .NET Compiler Platform( "Roslyn")の概要
  4. MSDN フォーラム Microsoft "Roslyn" CTP
  5. MSDN ロズリンのツアーに参加
  6. 今すぐRoslynを学びましょう
  7. ミゲル・デ・イカザ。 モノとロズリン

見つかったバグ


PVS-Studioアナライザーは、Roslynでエラーをほとんど見つけませんでした。 これは、デバッグされた品質管理システムを備えたマイクロソフトによって開発されているこのような有名なプロジェクトにとっては当然のことです。 Roslynコードで少なくとも何かを見つけることはすでに大きな勝利であり、それができることを誇りに思っています。

以下のエラーの多くは、テストまたはエラーハンドラーに関連しています。 これは自然なことです。 頻繁に使用されるコードフラグメントのエラーは、テストとユーザーフィードバックのおかげで修正されました。 しかし、私たちにとっては、PVS-Studioがエラーを見つけることができるという事実自体が重要です。 これは、多くの労力で修正された多くのエラーが、PVS-Studioの通常の使用ですぐに修正できることを意味します。

もう一度言います。 アナライザーの価値は、1回限りの起動ではなく、通常の使用にあります。 静的コード分析は、コンパイラ警告の拡張バージョンと見なすことができます。 1年に1回コンパイラ警告を含めるのは愚かです。 警告は発生した直後に確認する必要があります。 これは、デバッグを使用して愚かなバグを探すことにより、開発時間を節約します。 静的アナライザーでは、すべてが同じです。

PVS-Studioを使用して発見された興味深いものを見てみましょう。

テストのエラーN1。 コピーアンドペースト。
public void IndexerMemberRace() { .... for (int i = 0; i < 20; i++) { .... if (i % 2 == 0) { thread1.Start(); thread2.Start(); } else { thread1.Start(); thread2.Start(); } .... } .... } 

PVS-Studio警告: V3004 「then」ステートメントは「else」ステートメントと同等です。 GetSemanticInfoTests.cs 2269

これは、誰にもわずらわされないため、プロジェクト内で何年も生き続けることができるテストエラーの一例です。 テストでは、計画されたすべてがチェックされるわけではありません。 最初は常にストリーム1が開始され、次にストリーム2が開始されます。ほとんどの場合、次のようなテストを作成することが計画されていました。
 if (i % 2 == 0) { thread1.Start(); thread2.Start(); } else { //     thread2.Start(); thread1.Start(); } 

テストのエラーN2。 タイプミス。
 public DiagnosticAsyncToken( AsynchronousOperationListener listener, string name, object tag, string filePath, int lineNumber) : base(listener) { Name = Name; Tag = tag; FilePath = filePath; LineNumber = lineNumber; StackTrace = PortableShim.StackTrace.GetString(); } 

PVS-Studio警告: V3005 「名前」変数はそれ自体に割り当てられます。 AsynchronousOperationListener.DiagnosticAsyncToken.cs 32

ここでエラーを見つけるのは非常に難しいようです。 変数の命名に失敗しました。 クラスプロパティ名は、最初の大文字のみが関数の引数と異なります。 その結果、タイプミスをするのが簡単になりました。これは、名前=名前です。

エラーN3、N4。 コピーアンドペースト。
 private Task<SyntaxToken> GetNewTokenWithRemovedOrToggledPragmaAsync(....) { var result = isStartToken ? GetNewTokenWithPragmaUnsuppress( token, indexOfTriviaToRemoveOrToggle, _diagnostic, Fixer, isStartToken, toggle) : GetNewTokenWithPragmaUnsuppress( token, indexOfTriviaToRemoveOrToggle, _diagnostic, Fixer, isStartToken, toggle); return Task.FromResult(result); } 

警告PVS-Studio: V3012 「?:」演算子は、その条件式に関係なく、常に同じ値を返します。 AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs 177

「isStartToken」の値に関係なく、GetNewTokenWithPragmaUnsuppress()関数は実際の引数の同じセットで呼び出されます。 最も可能性が高いのは、Copy-Pasteを使用して関数呼び出しが複製された後、コピーされたコード内の何かを変更するのを忘れていたためです。

他の同様のケースを次に示します。
 private void DisplayDiagnostics(....) { .... _console.Out.WriteLine( string.Format((notShown == 1) ? ScriptingResources.PlusAdditionalError : ScriptingResources.PlusAdditionalError, notShown)); .... } 

PVS-Studio警告:V3012「?:」演算子は、その条件式に関係なく、常に1つの同じ値を返します:ScriptingResources.PlusAdditionalError。 CommandLineRunner.cs 428

エラーN5、N6。 不注意。

C#プログラマーが行う典型的なエラーに関する統計情報はまだほとんどありません。 しかし、標準的なタイプミスに加えて、次のエラーパターンが明らかになり始めます。多くの場合、「as」演算子を使用してリンクをキャストした後、結果のリンクではなく元のリンクをチェックします。 次に、未確認のリンクを使用します。 合成コード:
 var A = B as T; if (B) A.Foo(); 

そして、このエラーが実際にどのように見えるかを以下に示します。
 public override bool Equals(object obj) { var d = obj as DiagnosticDescription; if (obj == null) return false; if (!_code.Equals(d._code)) return false; .... } 

PVS-Studio警告: V3019 「as」キーワードを使用した型変換後、おそらく誤った変数がnullと比較されます。 変数「obj」、「d」を確認します。 DiagnosticDescription.cs 201

次の例はより冗長ですが、実際にはすべてが同じです:
 protected override bool AreEqual(object other) { var otherResourceString = other as LocalizableResourceString; return other != null && _nameOfLocalizableResource == otherResourceString._nameOfLocalizableResource && _resourceManager == otherResourceString._resourceManager && _resourceSource == otherResourceString._resourceSource && .... } 

PVS-Studio警告:V3019「as」キーワードを使用した型変換後、おそらく誤った変数がnullと比較されます。 変数「other」、「otherResourceString」を確認してください。 LocalizableResourceString.cs 121

エラーN7。 二重検出。

場合によっては、2つまたは3つのアナライザー警告が、コード内のエラーの存在をすぐに示します。 ここで、そのようなケースを検討します。
 private bool HasMatchingEndTag( XmlElementStartTagSyntax parentStartTag) { if (parentStartTag == null) { return false; } var parentElement = parentStartTag.Parent as XmlElementSyntax; if (parentStartTag == null) { return false; } var endTag = parentElement.EndTag; .... } 

PVS-Studioの警告:
関数の開始時に、引数 'parentStartTag'がNULL参照ではないことが確認されます。 ゼロの場合、関数は終了します。

次に、リンクが実際に「XmlElementSyntax」のようなクラスを指していることを確認したかったのです。 しかし、その瞬間にタイプミスがコードに忍び込みました。 「parentElement」をチェックする代わりに、「parentStartTag」が再チェックされます。

アナライザーは、一度に2つの異常に気付きます。 最初の異常: 'parentStartTag'の値を再チェックしても意味がありません。これがnull参照である場合、関数を既に残しているためです。 2番目の異常:アナライザーは、 'as'演算子の後に間違った変数をチェックすると疑っています。

コードの正しいバージョン:
 if (parentStartTag == null) { return false; } var parentElement = parentStartTag.Parent as XmlElementSyntax; if (parentElement == null) { return false; } 

エラーN8、N9。 コピーアンドペースト。

長いコードをおaびしますが、合成の例に置き換えたくありませんでした。
 internal static bool ReportConflictWithParameter(....) { .... if (newSymbolKind == SymbolKind.Parameter || newSymbolKind == SymbolKind.Local) { diagnostics.Add(ErrorCode.ERR_LocalSameNameAsTypeParam, newLocation, name); return true; } if (newSymbolKind == SymbolKind.TypeParameter) { return false; } if (newSymbolKind == SymbolKind.Parameter || newSymbolKind == SymbolKind.Local) { diagnostics.Add(ErrorCode.ERR_LocalSameNameAsTypeParam, newLocation, name); return true; } .... } 

PVS-Studio警告: V3021同一の条件式を持つ2つの「if」ステートメントがあります。 最初の「if」ステートメントにはメソッドの戻り値が含まれます。 これは、2番目の「if」ステートメントが無意味であることを意味しますInMethodBinder.cs 264

記事のコードスニペットでは、最初と3番目の「if」ステートメントが一致しています。 どうやらブロックがコピーされたので、彼らはその中の何かを変更するのを忘れていました。 可能ですが、繰り返される「if」は不要であり、削除する必要があります。

別の同様のコードがありますが、長い例で読者を悩ませることはありません。 診断警告を出すだけです:

V3021同一の条件式を持つ2つの「if」ステートメントがあります。 最初の「if」ステートメントにはメソッドの戻り値が含まれます。 これは、2番目の「if」ステートメントが無意味であることを意味しますWithLambdaParametersBinder.cs 131

エラーN10。 条件が無効です。
 public enum TypeCode { .... Object = 1, .... DateTime = 16, .... } static object GetHostObjectValue(Type lmrType, object rawValue) { var typeCode = Metadata.Type.GetTypeCode(lmrType); return (lmrType.IsPointer || lmrType.IsEnum || typeCode != TypeCode.DateTime || typeCode != TypeCode.Object) ? rawValue : null; } 

PVS-Studio警告: V3022式 'lmrType.IsPointer || lmrType.IsEnum || typeCode!= TypeCode.DateTime || typeCode!= TypeCode.Object 'は常にtrueです。 DkmClrValue.cs 136

式は非常に複雑なので、主なポイントを強調します。
 (typeCode != 1 || typeCode != 16) 

「typeCode」変数の値に関係なく、この式は常に真です。

エラーN11。 過剰な状態。
 public enum EventCommand { Disable = -3, Enable = -2, SendManifest = -1, Update = 0 } protected override void OnEventCommand( EventCommandEventArgs command) { base.OnEventCommand(command); if (command.Command == EventCommand.SendManifest || command.Command != EventCommand.Disable || FunctionDefinitionRequested(command)) .... } 

警告PVS-Studio: V3023この式の検査を検討してください。 表現が過剰であるか、誤植が含まれています。 RoslynEventSource.cs 79

ここでもポイントは次のとおりです。
 if (A == -1 || A != -3) 

この表現は誤っているか冗長です。 以下に縮小できます。
 if (A != -3) 

ロギング時のエラーN12。
 static CompilerServerLogger() { .... loggingFileName = Path.Combine(loggingFileName, string.Format("server.{1}.{2}.log", loggingFileName, GetCurrentProcessId(), Environment.TickCount)); .... } 

警告PVS-Studio: V3025の形式が正しくありません 。 「フォーマット」関数を呼び出すときに、異なる数のフォーマット項目が予想されます。 予想:2.現在:3. CompilerServerLogger.cs 49

変数 'loggingFileName'は、Format()関数を呼び出すときに使用されません。 これは疑わしいです。

エラーハンドラのエラーN13。
 private const string WriteFileExceptionMessage = @"{1} To reload the Roslyn compiler package, close Visual Studio and any MSBuild processes, then restart Visual Studio."; private void WriteMSBuildFiles(....) { .... catch (Exception e) { VsShellUtilities.ShowMessageBox( this, string.Format(WriteFileExceptionMessage, e.Message), null, OLEMSGICON.OLEMSGICON_WARNING, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } } 

警告PVS-Studio:V3025の形式が正しくありません。 「フォーマット」関数を呼び出すときに、異なる数のフォーマット項目が予想されます。 予想:2.現在:1. CompilerPackage.cs 105

どうやら、メッセージボックスを表示しようとすると、例外がスローされます。 実際、Format()関数は2番目の追加の引数を出力しようとします。 しかし、彼はそうではありません。

書式設定を指定する一定の行は次のように始まる必要があるように思えます:
 @"{0} 

エラーハンドラのエラーN14、N15。

DumpAttributes()関数はまだ使用されていないと思います。 これには一度に2つのエラーが含まれており、それぞれが例外の生成につながるはずです。
 private void DumpAttributes(Symbol s) { int i = 0; foreach (var sa in s.GetAttributes()) { int j = 0; foreach (var pa in sa.CommonConstructorArguments) { Console.WriteLine("{0} {1} {2}", pa.ToString()); j += 1; } j = 0; foreach (var na in sa.CommonNamedArguments) { Console.WriteLine("{0} {1} {2} = {3}", na.Key, na.Value.ToString()); j += 1; } i += 1; } } 

PVS-Studioの警告:
どちらの場合も、WriteLine()関数が呼び出されると、必要とするよりも少ない実際の引数を受け取ります。 その結果、FormatExceptionがスローされます。

エラーN16。 危険な表現。

今、次のコードフラグメントを見て、理解したくないと確信しています。 これは、疲れのないコードアナライザーの有用性を示しています。
 private static bool SymbolsAreCompatibleCore(....) { .... var type = methodSymbol.ContainingType; var newType = newMethodSymbol.ContainingType; if ((type != null && type.IsEnumType() && type.EnumUnderlyingType != null && type.EnumUnderlyingType.SpecialType == newType.SpecialType) || (newType != null && newType.IsEnumType() && newType.EnumUnderlyingType != null && newType.EnumUnderlyingType.SpecialType == type.SpecialType)) { return true; } .... } 

PVS-Studio警告: V3027変数 'newType'は、同じ論理式でnullに対して検証される前に、論理式で使用されました。 AbstractSpeculationAnalyzer.cs 383

コードの危険性を明確にするために、それに基づいた簡単な合成例を作成します。
 if ((A != null && Ax == By) || (B != null && Bq == Aw)) 

ご覧のとおり、AとBはnull参照になる可能性があることが理解されます。 式は2つの部分で構成されます。 最初の部分ではリンクAがチェックされますが、リンクBはチェックされず、2番目の部分ではリンクBがチェックされますが、リンクAはチェックされません。

運のおかげでコードは機能するかもしれませんが、非常に疑わしく危険です。

エラーN17、N18。 繰り返し割り当て。
 public static string Stringize(this Diagnostic e) { var retVal = string.Empty; if (e.Location.IsInSource) { retVal = e.Location.SourceSpan.ToString() + ": "; } else if (e.Location.IsInMetadata) { return "metadata: "; } else { return "no location: "; } retVal = e.Severity.ToString() + " " + e.Id + ": " + e.GetMessage(CultureInfo.CurrentCulture); return retVal; } 

PVS-Studio警告: V3008 「retVal」変数には連続して2回値が割り当てられます。 おそらくこれは間違いです。 行を確認してください:324、313。DiagnosticExtensions.cs 324

「if」演算子の分岐の1つで、「retVal」の値が割り当てられていることに注意してください。 ただし、関数の最後に、変数「retVal」の値が上書きされます。 よくわかりませんが、最後の課題は次のようになります。
 retVal = retVal + e.Severity.ToString() + " " + e.Id + ": " + e.GetMessage(CultureInfo.CurrentCulture); 

別の同様のケースを考えてみましょう
 public int GetMethodsInDocument( ISymUnmanagedDocument document, int bufferLength, out int count, ....) { .... if (bufferLength > 0) { .... count = actualCount; } else { count = extentsByMethod.Length; } count = 0; return HResult.S_OK; } 

PVS-Studio警告:V3008「count」変数には、連続して2回値が割り当てられます。 おそらくこれは間違いです。 行を確認:317、314。SymReader.cs 317

関数は、「count」への参照によって値を返します。 関数の異なる部分では、「count」に異なる値が書き込まれます。 関数の最後に、常に0が常に「count」に書き込まれるのは疑わしいです。

テストのエラーN19。 タイプミス。
 internal void VerifySemantics(....) { .... if (additionalOldSources != null) { oldTrees = oldTrees.Concat( additionalOldSources.Select(s => ParseText(s))); } if (additionalOldSources != null) { newTrees = newTrees.Concat( additionalNewSources.Select(s => ParseText(s))); } .... } 

PVS-Studio警告: V3029互いに並んでいる「if」演算子の条件式は同一です。 行を確認してください:223、228。EditAndContinueTestHelpers.cs 223

2番目の条件では、「additionalOldSources」ではなく「additionalNewSources」を確認する必要がありました。 リンク 'additionalNewSources'が突然nullになった場合、Select()関数を呼び出そうとすると例外がスローされます。

エラーN20。 物議を醸すから。

当然、この記事では、PVS-Studioアナライザーが発行したすべての警告を分析しませんでした。 明らかな誤検知は数多くありますが、コードにエラーが含まれているかどうかを判断するRoslynプロジェクトについての知識がないだけの場合もあります。 これらのケースの1つを検討してください。
 public static SyntaxTrivia Whitespace(string text) { return Syntax.InternalSyntax.SyntaxFactory.Whitespace( text, elastic: false); } public static SyntaxTrivia ElasticWhitespace(string text) { return Syntax.InternalSyntax.SyntaxFactory.Whitespace( text, elastic: false); } 

V3013 「Whitespace」関数の本体が「ElasticWhitespace」関数の本体と完全に同等であることは奇妙です(118、129行目)。 SyntaxFactory.cs 118

2つの関数の本体は同一です。 これは、アナライザーの観点からは疑わしいです。 これらの機能は私には疑わしいです。 しかし、私はプロジェクトを知りません、そしておそらくコードは正しく書かれています。 したがって、私は仮定のみを行います。 おそらく、ElasticWhitespace()関数内では、実際の「elastic」パラメーターを「true」に設定する必要があります。

エラーNxx。

上記のように、このような各ケースを詳細に扱うことはできないことを読者に理解していただきたいと思います。 私は多くのプロジェクトをチェックしていますが、それぞれは私には馴染みがありません。 したがって、最も明らかな間違いのみを記事で説明します。 この記事では、このような20のケースに焦点を当てました。 ただし、PVS-Studioはより多くの欠陥を検出できたと思います。 したがって、Roslyn開発者はこの記事だけに頼るのではなく、自分でプロジェクトを確認することをお勧めします。 このデモ版ではアナライザーでは十分ではありませんが、しばらくの間ライセンスキーを提供する準備ができています。

ReSharperとの比較


私はC#プロジェクトのチェックに関する記事をかなり書いて、たった1つの会議で話をしました。 しかし、質問をするたびに「ReSharperとの比較はありますか?」

この質問は2つの理由で好きではありません。 まず、これらはまださまざまな種類のツールです。 PVS-Studioは、バグの検出に焦点を当てた古典的なコードアナライザーです。 ReSharperは、プログラミングを容易にし、多数の推奨事項を提供できるように設計された生産性向上ツールです。

PVS-StudioとReSharperは、多くの問題に対してまったく異なるアプローチを採用しています。 たとえば、PVS-Studioには各診断の詳細な説明 、コードを修正するための例、ヒントが記載されたドキュメントがあります。 ReSharperの場合、「C#、VB.NET、XAML、XML、ASP.NET、ASP.NET MVC、Razor、JavaScript、TypeScript、HTML、CSS、ResXでの1400のコード検査」 に関する記述があります。 1400という数字はしっかりしているように見えますが、実際には何も意味しません。 おそらくどこかでこれらのすべてのコード検査の説明がありますが、すぐには見つかりませんでした。 ReSharperがC#プログラムで検出したエラーを正確に読み取ることができない場合、ツールを比較するにはどうすればよいですか。

第二に、我々が行う比較は完全に批判されます。 私たちはすでにこれを経験しており、比較を続けることを約束しました。 たとえば、CppcheckとVisual Studio SCAを使用してPVS-Studioに慎重にアプローチしました。 多くの時間と労力が費やされました。 結果は、 簡潔詳細なバージョンで提示されました。 その後、怠zyな人だけが、私たちがすべて間違ったことを書いたり、検証のために特別に選択されたプロジェクトのために私たちの比較が不公平であると書いていない。

比較する時間を無駄にすることはありません。 どれほど慎重かつ正直に彼にアプローチしても、比較には偏りがあったと言うことができます。

それにもかかわらず、ReSharperよりも優れているかどうかの答えがあるはずです。 そして、私はそのような答えを持っています。

すでにReSharperを使用していますか? いいね! PVS-Studioをインストールして、プロジェクトのエラーを見つけてください!

おわりに


PVS-Studioのダウンロードを遅らせず、プロジェクトをテストしないことをお勧めします。 間違いがありますか? しかし、かなり機能するコードがあります。 ほとんどの場合、見つかったエラーは、コードのめったに使用されない部分にあります。 頻繁に使用されるコードのセクションでは、このようなエラーはゆっくりと痛みを伴うものの、修正されました。 PVS-Studioアナライザーが通常の使用でどれだけエネルギーを節約できるか想像してみてください。 もちろん、アナライザーはすべてのエラーを検出することはできません。 しかし、タイプミスや失策を探す時間を無駄にするよりも、利益を生む方が良いでしょう。 そして、PVS-Studioによって破られるように愚かな間違いを与えます。

PSあなたは愚かな間違いをしないのですか? まあまあ。 そうだけのようです。 彼らはすべてをします。 少なくともここを見てください。


この記事を英語圏の聴衆と共有したい場合は、翻訳へのリンクを使用してください:Andrey Karpov。 新年PVS-Studio 6.00リリース:スキャンRoslyn

記事を読んで質問がありますか?
多くの場合、記事には同じ質問が寄せられます。 ここで回答を集めました: PVS-Studioバージョン2015に関する記事の読者からの質問への回答 。 リストをご覧ください。

Source: https://habr.com/ru/post/J273811/


All Articles