使用整数表达式边界编写编译器绑定的检查数组(最佳实践) 我是用C++编写的一个编译器(C++ 98),我在寻找反馈/想法,如何处理下面的情况(参见语法的数组的标题):< /P>
绑定检查、运行时堆栈扩展(以及离开作用域时的收缩)等都可以在我的框架中很好地处理 我的问题涉及在使用未初始化变量的情况下发出警告,如上文(1)所示。如果a是一个在初始化前使用的整数变量,我允许它,但会发出警告消息。因为我想让编译器准备好以后可能有一个链接器,向后计算b和m并实际检查a的索引是否已初始化是不可能的(例如,在最常见的情况下,可以在不同的文件中定义一个变量)。如前所述,我知道如何发出代码在运行时执行绑定检查;但是 当一个变量未初始化使用到形式为a[(expr)]的情况时,发出警告的最佳实践方式是什么?由于(expr)不必是整数值(仅仅是一个数字;它只需要是整数类型),如果不计算(expr)(我不想像上面所说的那样进行计算),我就不能保留(比如)带有标记为initialized的项的阴影数组。在(gcc)C中,这种情况被简单地忽略:发出一个警告,表明b和m都未初始化,但没有一个警告与使用未初始化的变量a[b*m]有关。这显然符合C对数组的看法,在C中(但不是我正在研究的语言,它没有指针的概念),表达式定义得很好,除了b和m没有初始化,并且访问(可能)越界(即将发生的堆栈溢出)使用整数表达式边界编写编译器绑定的检查数组(最佳实践) 我是用C++编写的一个编译器(C++ 98),我在寻找反馈/想法,如何处理下面的情况(参见语法的数组的标题):< /P>,c++,arrays,compiler-construction,compiler-warnings,C++,Arrays,Compiler Construction,Compiler Warnings,绑定检查、运行时堆栈扩展(以及离开作用域时的收缩)等都可以在我的框架中很好地处理 我的问题涉及在使用未初始化变量的情况下发出警告,如上文(1)所示。如果a是一个在初始化前使用的整数变量,我允许它,但会发出警告消息。因为我想让编译器准备好以后可能有一个链接器,向后计算b和m并实际检查a的索引是否已初始化是不可能的(例如,在最常见的情况下,可以在不同的文件中定义一个变量)。如前所述,我知道如何发出代码在运行时执行绑定检查;但是 当一个变量未初始化使用到形式为a[(expr)]的情况时,发出警告的最佳
最好的做法是不检查[(expr)]在使用前是否已初始化;发射代码;并等待运行时错误(如果有)?或者…?我认为尝试初始化检查一切会导致痛苦 考虑当
a[b*m]
的元素被有条件地初始化时会发生什么,即a
的元素被初始化取决于输入参数。您不仅要跟踪“影子数组副本”中的初始化位,还要跟踪整个条件执行图,以确保覆盖所有执行路径。最终,这在图灵机器上是一个无法确定的问题,甚至;要解决这个问题,您必须决定(判断执行图的任何特定子图是否完成执行)
您可以使用一些启发式方法仅对未初始化的情况的某些子集发出警告,但这只意味着您的编译器有时会发出警告,而不是其他时候。作为一个程序员,你应该知道这种看似不确定的行为是多么令人恼火。 几乎不可能在每种情况下都能说出,例如,考虑一下:
void foo(int &x, int y)
{
switch(y)
{
case 1:
x = 11;
break;
case 2:
x = 42;
break;
... // numbers 3-9 elided for brevity
case 10:
x = 97;
break;
}
}
int bar(int z)
{
int a;
foo(a, z);
}
a
是否已初始化?这取决于z
的值。如果您有所有可用的代码,至少在理论上,您可以按照所有路径查看z
将有哪些可能的值(当然,假设,z
不是来自外部源的输入——在这种情况下,如果不进行范围检查,则可能是写得不好的代码,但很多代码都会欣然接受输入为“ok”)
因此,您必须选择两条路线中的一条:
当然,在编译阶段尽可能多地捕捉信息总是更好的——这只是一个你是否能够可靠地做到这一点(以及需要多少努力/时间)的问题。在代码编译后的测试中,你检测到的任何东西都会“花费”更多的时间来查找和修复。你的标题与你的问题文本不匹配 假设您的问题是:“如何检测未定义变量的使用”,如果您的语言不打算达到极高的性能,您可以始终为表示“未定义”的值定义一个位模式(对于32位有符号整数,-2^31非常好),并生成代码,在获取时检查未定义的值。这非常简单 如果您的问题是“如何检测越界数组访问”,尤其是考虑到您的语言没有
void foo(int &x, int y)
{
switch(y)
{
case 1:
x = 11;
break;
case 2:
x = 42;
break;
... // numbers 3-9 elided for brevity
case 10:
x = 97;
break;
}
}
int bar(int z)
{
int a;
foo(a, z);
}