C++测试编译错误
C++ testing for compile errors
我是一名学生,我正在为作业编写并运行一些测试代码,以便在交作业之前对其进行检查。我现在要做的是测试我的代码是否正确地阻止了值语义。在我的赋值中,我为我的每个类声明了它自己的private复制构造函数和赋值运算符,它们没有定义,所以什么也不做。当它们在我的测试程序中被调用时,我会像预期的那样出现编译错误。类似这样的东西:
错误:"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'"出现的特定编译错误?
谢谢你的帮助!
附言:这是我的第一个帖子,希望我已经做了";足够的";研究,其他一切都做得很好。对不起,如果我没有。
这些是编译器错误,而不是异常。异常是程序员抛出运行时错误并捕获/处理它们的一种机制。编译器甚至无法生成可执行文件供您运行,因为它识别出代码格式错误并且是无效的C++代码。
如果您想将其设为运行时错误,请将该方法设为public/use friends/无论您需要做什么来提供对某些内容的访问,并在方法的定义中抛出异常,在调用代码中捕获并处理异常。
然而,我认为这样做没有任何意义。总是喜欢编译时错误而不是运行时错误。总是
C++标准定义了什么是有效的或无效的代码,有些东西是未定义的,而其他东西则由实现编译器的人决定。任何符合标准的C++编译器都会出现错误,因为某些内容不符合标准/定义,因此是无效的。错误通常是说有些东西模棱两可或毫无意义,你需要修改你写的东西。
运行时错误要么是崩溃,要么是从用户的角度来看是无意的和不需要的行为。编译器错误是编译器说"我不明白你在说什么。这没有意义。"。编译器警告是编译器说:"我会让你这么做,但我可能不应该。你真的确定这是你的意思吗?"。
try-catch发生在运行时,而编译器静态地尝试链接您在编译时调用的函数,因此编译总是会失败。
或者,如果您愿意使用C++异常,那么您可以只实现复制和赋值方法,将它们公开,并在这些函数的主体中抛出异常。请注意,基本上在所有情况下,如果可以选择的话,您应该更喜欢静态/编译时检查而不是运行时检查。
在做了更多的研究之后,似乎没有(简单的)方法来测试C++中的某些编译错误
我认为,如果您可以使用C++2a
,情况可能不再如此。
由于我目前正在为模板化代码编写测试,我还尝试测试编译时的错误。
特别是,我想测试negative feature
,从而保证某些构造将无法编译。使用如下c++20
requires
表达式,这是可能的:
简单示例
下面,我检查不存在的函数invalid_function
不能在类型为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.");
请注意,您可以用测试框架的appropriate函数来替换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>);
}
该代码可在编译器资源管理器上获得。
用例
我将其用于模板元编程,以确保代码符合某些理论约束。
您真正想要测试的不是编译器失败,而是您想要测试关于类的某些假设。
在测试文件中,放入#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进行编译才能使用这些函数中的大部分。
(如断言代码不编译中首先描述的)
这种编译错误是无法抑制的。从C++标准的角度来看,它们是错误的。
当然,您可以在自己的(或修补的)编译器中压制其中一些。
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- std::is_base_of表示ctor编译错误
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- Qt Cmake 错误编译"GuiSupportQt not found"
- Opengl 精度转换错误编译错误 E0415
- 库将ARM架构错误编译为架构X64
- RT 音频 Mac 错误 g++ 编译错误
- 错误编译Boost.log
- 错误编译QT创建者 / QT窗口小部件示例
- 错误编译MIPS32
- Visual Studio 2013 中的错误(编译和运行代码)
- 链接错误编译qt项目在visual 2010
- 无法用模板错误编译nsgmls
- 奇怪的错误.编译失败
- 如果有人调用c++中的方法,则强制错误(编译时)
- 来自autoconf测试的错误编译命令
- 时间限制超出错误C++编译
- SFML 2.3 和 CodeBlocks 错误编译