运行时边界数组的源级别检测有多困难



"具有自动存储持续时间的运行时大小的阵列(N3639)"的(已接受的)提案声称

堆栈溢出的可能性更大,特别是在大小取决于外部输入且未正确检查的情况下因此,某些环境可能会禁止使用该功能。使用静态分析工具可以很容易地执行这样的禁令

如果需要分析器实现一个完整的C++编译器,我认为强制执行并不容易。

考虑以下代码:

template<typename T>
inline void array_user( const T& x )
{
    int a[f(traits<T>::omega)];
}

在我看来,每次使用array_user<T>都需要重复分析,并考虑:

  • 可在array_user<T>的使用点发现的traits<T>的适用专业化
  • traits<T>::omega是否是编译时常数表达式(通过constexprenum等C++03方法)
  • traits<T>::omega的类型
  • f()的适用过载(在使用array_user<T>时,可能通过ADL发现)是否为constexpr

我是不是错过了什么?是否可以在不经过全面编译的情况下强制执行这样的限制?

可以用这种方式编写代码来简化对不使用运行时边界的验证吗?

如果我的任务是编写一个分析器来静态验证不使用运行时边界,我会拒绝上面的代码。我要求所有数组声明要么为绑定使用整型文字,要么进行注释以使编译器拒绝运行时边界。

template<typename T>
inline void array_user( const T& x )
{
    int a[f(traits<T>::omega)];
    sizeof a;
}

然而,考虑到目前以C++模式提供C99风格VLA作为扩展的编译器的数量,我不确定它们是否真的符合禁止sizeof的C++14行为。

最新更新