源级检测运行时边界数组有多难?

Ben*_*igt 6 c++ arrays static-analysis c++14

"已接受的"提议"具有自动存储持续时间(N3639)的运行时大小的数组"断言

堆栈溢出变得更有可能,特别是如果大小取决于外部输入并且未正确检查.因此,某些环境可能会禁止使用该功能.使用静态分析工具可以很容易地实施这种禁止.

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

请考虑以下代码:

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

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

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

我错过了什么吗?是否可以在不经过完整编译的情况下强制执行此类限制?

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

Ben*_*igt 1

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

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

然而,考虑到当前在 C++ 模式下提供 C99 样式 VLA 作为扩展的编译器数量,我不相信它们实际上会符合禁止 的 C++14 行为sizeof