什么是测试标识符没有被截断并因此混淆的好方法?

时间:2011-09-13 04:56:18

标签: c++ unit-testing language-design compiler-construction

在今天的C ++类中,我们讨论了标识符的最大可能长度,以及编译器在一定长度后如何最终停止将变量视为不同的变量。 (我的教授似乎暗示了很长的标识符会被截断。)posted another question earlier, hoping to see if the limit is defined somewhere。我的问题有点不同。假设我想测试标识符名称长度的实际或强制限制。我该怎么做呢?这是我正在考虑的事情,但不知何故,它似​​乎太简单了。

  • 步骤1:使用非常长的名称生成至少两个变量并将其打印到控制台。如果标识符名称确实无限制,我不会浪费时间输入它们。我的代码应该为我做。
  • 第2步:尝试对变量执行某些操作,例如比较它们或任何算术。如果编译器停止区分,那么理论上,某些算法会中断,例如x/(reallyLongA-reallyLongB),因为reallyLongAreallyLongB将会很长,以至于编译器会将它们视为同一个东西。在这一点上,分裂操作将变成一个零分割,它应该崩溃并且可怕地燃烧。

我接近这个吗?在“打破”编译器或“运行时”之前,我是否会耗尽内存?

3 个答案:

答案 0 :(得分:5)

我认为您甚至不需要对变量生成任何操作。

以下代码将在编译时生成重定义错误;

int name;
int name;

我希望你和

一起犯同样的错误
int namewithlastsignificantcharacterhere_abc;
int namewithlastsignificantcharacterhere_123;

我会使用脚本语言来生成连续更长的名字,直到你有一个破坏的名字。这是一个Ruby单行

  

C:> ruby​​ -e“(1..2048).each {| i | puts \”int#{'variable'* i}#{i}; \“}”> var.txt

当我在c文件中#include var.txt,并使用VS2008编译时,我收到错误

  

“1> c:\ code \ quiz \ var.txt(512):致命错误C1064:编译器限制:令牌溢出的内部缓冲区”

和512 * 8字符是JRL引用的4096。

答案 1 :(得分:4)

Windows C++

  

只有Microsoft C ++标识符的前2048个字符   重大。用户定义类型的名称由“装饰”   编译器保存类型信息。结果名称,包括   类型信息,不能超过2048个字符。

因此,您似乎可以使用MS编译器进行非常简单的测试,至少。

修改 没有进行大量的测试,但至少在我的Visual Studio Pro 2008上,一个名为aaaa的变量...(总长度为4095个字符)进行编译,之后(> = 4096得到Fatal Error C1064: compiler limit : token overflowed internal buffer)。 / p>

答案 2 :(得分:4)

你的教授错了。 C ++标准的第2.11 / 1条说:“所有字符都很重要”。当然,编译器可能会对允许的长度施加限制,如您的其他问题所述。这并不意味着他们可以在此之后忽略字符。

他可能会混淆C和C ++。这两种语言有相似但不完全相同的规则。从历史上看,C有六个重要字符的限制。

至于你的测试,有一种很简单的方法来测试你的假设。注意

int a;
int a;

是非法的,因为您定义了两次相同的标识符。现在如果 ReallyLongNameAReallyLongNameB仅在非重要字符方面有所不同,那么

int ReallyLongNameA;
int ReallyLongNameB;

也是编译时错误,因为两者都会声明相同的变量。您不需要运行代码。您可以使用这两行生成test.cpp,并尝试编译它。因此,编写一个小型测试程序,创建越来越长的标识符名称,将其写入test.cpp,然后调用system("path/to/compiler -compileroptions test.cpp");以查看它是否编译。