5

私は学生で、課題を提出する前にそれをチェックするために、いくつかのテスト コードを作成して実行しようとしています。私の割り当てでは、クラスごとに独自のプライベートコピーコンストラクターと割り当て演算子を宣言しましたが、これらには定義がないため、何もしません。それらがテスト プログラムで呼び出されると、予期したとおりにコンパイル エラーが発生します。このようなもの:

エラー: 'myClass::myClass(const &myClass)' はプライベートです'

エラー: 'myClass& myClass::operator=(const myClass&)' は非公開です

テスト コードをコンパイルして実行するために try/catch を使用する方法はありますか? 私はもう試した:

myClass obj1(...);
myClass obj2(...);
try{
  obj1 = obj2;
  throw 1;
}
catch(int e){
  assert(e==1);
}

しかし、コンパイラはまだ上記のエラーを出しています。これらは「例外」ではありませんか?彼らはスローをトリガーしませんか?

私が try/catch を正しく理解していれば、上記の種類のエラーではなく、実行時エラーを処理します。正しいですか?

さらに調査を行った結果、特定のコンパイル エラーを C++ 内でネイティブにテストする (簡単な) 方法はないようです (考えてみると、これはほとんどの言語に当てはまる可能性があります)。C++ コードのスニペットをコンパイルしてエラーをチェックするスクリプト言語でテスト コードを作成することを提案する投稿と、 Boost.Build の使用を推奨する別の投稿を読みました。

私がやろうとしていることを行うための最も簡単で最良の方法は何ですか?

Boost.Build のドキュメントを見ましたが、ちょっと頭がおかしいです。私がそれを使用した場合、「test.cpp」などのファイルがコンパイルされることをどのようにテストし、「test.cpp」で発生する特定のコンパイル エラーを処理するのでしょうか?

ご協力いただきありがとうございます!

PS これは私の最初の投稿の 1 つです。「十分な」調査を行い、他のすべてを適切に行ったことを願っています。しなかったらごめんなさい。

4

5 に答える 5

4

これらはコンパイラ エラーであり、例外ではありません。例外は、プログラマーが実行時エラーをスローし、それらをキャッチ/処理するためのメカニズムです。コンパイラは、コードの形式が正しくなく、無効な C++ コードであることを認識するため、実行する実行可能ファイルをビルドすることさえできません。

これを実行時エラーにしたい場合は、メソッドをパブリックにする/フレンドを使用する/何かへのアクセスを提供し、メソッドの定義で例外をスローするために必要なことは何でも、呼び出し元のコードで例外をキャッチして処理します。

ただし、これを行う目的はありません。常に実行時エラーよりもコンパイル時エラーを優先します。いつも。

C++ 標準では、コードの有効性と無効性が定義されています。未定義のものもあれば、コンパイラの実装者に任されているものもあります。標準準拠の C++ コンパイラは、何かが標準/定義を満たしていないために無効であるため、エラーを返します。エラーは一般的に、何かが曖昧であるか、まったく無意味であり、書いたものを修正する必要があることを示しています。

実行時エラーは、クラッシュ、またはユーザーの観点からは意図されていない望ましくない動作のいずれかです。コンパイラ エラーとは、コンパイラが「あなたの言っていることが理解できません。これは意味がありません。」と言っているエラーです。コンパイラの警告は、コンパイラが「これをやらせますが、おそらくやるべきではありません。これがあなたの意図したことであると本当に確信していますか?」と言っています。

于 2012-03-29T01:03:05.737 に答える
4

try-catch は実行時に発生しますが、コンパイラはコンパイル時に呼び出している関数を静的にリンクしようとするため、コンパイルは常に失敗します。

または、C++ 例外を使用する場合は、コピー メソッドと代入メソッドを実装し、それらを公開して、それらの関数の本体で例外をスローするだけです。基本的にすべての状況で、選択肢がある場合は、実行時チェックよりも静的/コンパイル時チェックを優先する必要があることに注意してください。

于 2012-03-29T00:50:17.470 に答える
3

本当にテストしたいのは、コンパイラの失敗ではなく、クラスに関する特定の仮定をテストすることです。

テストファイルに、#include <type_traits>

そして追加

assert((std::is_assignable <myClass, myClass> ::value) == FALSE);
assert((std::is_copy_assignable<myClass> ::value) == FALSE);
assert((std::is_copy_constructible<myClass> ::value) == FALSE);

チェックできるさまざまな特性は、ここに記載されています: http://en.cppreference.com/w/cpp/types

これらの関数のほとんどを使用するには、C++11 用にコンパイルする必要があることに注意してください。

(コードがコンパイルされないことをアサートするで最初に説明したように)

于 2015-11-03T16:17:49.760 に答える
3

さらに調査を行った結果、特定のコンパイル エラーを C++ 内でネイティブにテストする (簡単な) 方法はないようです。

使えるようになればもうそんなことはないのではないかと思いますC++2a

現在、テンプレート化されたコードのテストを書いているので、コンパイル時のエラーもテストしようとしました。

特に、 をテストしたいnegative featureので、特定の構造がコンパイルに失敗することを保証します。これはc++20 requires、次のような式を使用して可能です。

簡単な例

以下では、存在しない関数invalid_functionを Struct 型で呼び出すことができないことを確認しSます。

struct S {}; //< Example struct on which I perform the test
template <typename T> constexpr bool does_invalid_function_compile = requires(T a) {
  a.invalid_function();
};
static_assert(!does_invalid_function_compile<S>, "Error, invalid function does compile.");

テスト フレームワークの適切な関数で static_assert を置き換えることができることに注意してください。これにより、実行時にテスト エラーが記録されるため、このコンパイル テストを回避して他のテストの実行を停止できます。

フォームの質問例

もちろん、この例は、質問に示されているシナリオで動作するように適合させることができます。これは、おおよそ次のようになります。

/// Test struct with deleted assignment operator
struct myClass {
  auto operator=(myClass const &) = delete;
};
/// Requires expression which is used in order to check if assigment is possible
template <myClass cl1, myClass cl2> constexpr bool does_assignment_compile = requires() {
  cl1 = cl2;
};


int main() {
  myClass cl1;
  myClass cl2;
  // Note that static assert can only be used if this can be known at compile time. Otherwise use
  // the boolean otherwise.
  static_assert(!does_assignment_compile<cl1, cl2>);
}

コードはCompiler Explorerで入手できます。

ユースケース

コードが特定の理論的制約に準拠していることを確認するために、テンプレート メタプログラミングにこれを使用します。

于 2020-03-26T10:08:34.280 に答える
0

この種のコンパイル エラーは抑制できません。これらは、C++ 標準の観点から見たエラーです。

確かに、それらのいくつかは、独自の (またはパッチを適用した) コンパイラで抑制することができます。

于 2012-03-29T00:51:43.127 に答える