2012-03-29 91 views
3

我是一名学生,我正在尝试编写并运行一些测试代码,以便在调用之前检查它。我现在想要做的是测试我的代码正确地阻止了值语义。在我的任务中,我已经为我的每个类声明了自己的专用复制构造函数和赋值运算符,它们没有定义,因此什么都不做。当他们在我的测试程序中被调用时,我得到了像我预期的编译错误。事情是这样的:编译错误的C++测试

error: 'myClass::myClass(const &myClass)' is private'

error: 'myClass& myClass::operator=(const myClass&)' is private

是否有使用try/catch语句,这样我的测试代码编译和运行,但告诉我,这些错误确实发生的方法吗? 我已经试过:

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

但是编译器仍然给我上述错误。这些不是'例外'吗?他们会不会引发一次投掷?

如果我正确理解try/catch,它会处理运行时错误,而不是我上面得到的那种错误,对吗?

在做了一些更多的研究之后,似乎没有(简单的)在C++中本地测试某些编译错误的方法(对于大多数语言来说,现在我认为它可能是这样)。我读了post,建议用脚本语言编写一些测试代码,尝试编译C++代码片段并检查是否有任何错误,另一个建议使用Boost.Build的post

做什么我想要做什么是最简单/最好的方式?

我看了看Boost.Build的文档,它有点凌驾于我的头上。如果我使用它,我将如何测试一个文件,比如'test.cpp'编译,并且可能处理'test.cpp'发生的特定编译错误?

感谢您的帮助!

P.S.这是我的第一篇文章之一,希望我已经做了“足够”的研究,并且正确地完成了一切。对不起,如果我没有。

+0

只要您编译程序,你会得到一个错误列表。这还不够?!如果你添加一个测试类,那就不能从你的代码中提取更多的“编译错误”。测试类被写入(编译后)运行代码并提取语义错误。 – Shahbaz 2012-03-29 09:25:27

+0

在这种情况下,我只需要进行一些我想测试的操作,但仔细阅读编译错误并不是什么大不了的事情。但是当你在一个大项目上工作时,会发生什么情况,并且有很多您想要防止的操作/行为,您想要产生编译错误的操作/行为?手动阅读并检查每一个看起来不仅有点乏味。 – 2012-03-29 15:52:59

+0

等待,您不能为运行时操作/行为“产生编译错误”。编译器读取您的代码,确保它符合C++语言,从词汇,语法和语义上都符合C++语言,并为其生成代码。它只检查C++语言指定的内容。如果生成的代码不起作用,那与编译器无关(所以它不能给你编译错误) – Shahbaz 2012-03-29 16:07:47

回答

3

这些是编译器错误,不是例外。异常是程序员抛出运行时错误并捕获/处理它们的机制。编译器甚至无法为您创建可执行文件,因为它可以识别代码格式错误并且是无效的C++代码。

如果你想使这是一个运行时错误,使该方法公开/使用朋友/无论你需要做什么来提供对某些东西的访问并在方法的定义中抛出一个异常,捕获并处理异常调用代码。

但是我没有看到这样做的目的。总是比运行时错误更喜欢编译时错误。总是。

C++标准定义了什么是有效或无效的代码,有些东西还没有定义,剩下的东西留给谁来实现编译器。任何符合标准的C++编译器都会出错,因为某些内容不符合标准/定义,因此无效。这些错误通常是说某些东西模棱两可或者直接无意义,你需要修改你写的东西。

运行时错误是崩溃或从用户的角度来看是不想要的和不需要的行为。编译器错误是编译器说:“我不明白你在说什么,这没有意义。”编译器的警告是编译器说:“我会让你这样做,但我可能不应该,你确定这是你的意思吗?”。

+2

+1:'总是喜欢编译时错误到运行时错误' – 2012-03-29 01:04:38

3

try-catch在运行时发生,而编译器会静态地尝试链接您在编译时调用的函数,因此编译将始终失败。另外,如果你愿意使用C++异常,那么你可以实现复制和赋值方法,使它们公开,并在这些函数的主体中引发异常。请注意,在基本上每种情况下,如果您有选择,您应该优先选择运行时检查的静态/编译时检查。

+0

感谢Preet,我这样做,它帮助我更多地理解异常。我现在明白编译时检查是更可取的。 – 2012-03-29 01:18:10

0

这种编译错误不能被抑制。他们是来自C++ standarts'观点的错误。

当然,你可以在你自己的(或修补过的)编译器中抑制它们中的一些。

1

你真正想测试的不是编译器失败,而是你想测试关于你的类的某些假设。

在您的测试文件,把#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使用这些功能的大部分。

(如Assert that code does NOT compile首次描述)

+0

更好的是使用static_assert而不是assert,以便它会触发编译错误。 – Tomis 2016-08-19 14:42:14