C++ 在这种情况下,C++;在编译时进行数组边界检查吗?
受“”思想的启发,我试图编写一个示例类来检查字符串中的第一个字符是否为C++ 在这种情况下,C++;在编译时进行数组边界检查吗?,c++,arrays,c++11,indexoutofboundsexception,C++,Arrays,C++11,Indexoutofboundsexception,受“”思想的启发,我试图编写一个示例类来检查字符串中的第一个字符是否为a int dummy[0]; class Test { public: constexpr Test(const char *p):p_(p){} constexpr void check()const { if (p_[0]!='a') dummy[1]=0; } const char *p_; }; constexpr Test oper
a
int dummy[0];
class Test
{
public:
constexpr Test(const char *p):p_(p){}
constexpr void check()const
{
if (p_[0]!='a')
dummy[1]=0;
}
const char *p_;
};
constexpr Test operator"" _test(const char *pszText, size_t)
{
Test t(pszText);
t.check();
return t;
}
int main()
{
//dummy[1] = 0;
constexpr Test t = "baa"_test;
}
它运行良好(Ubuntu上的GCC7.1)。如果第一个字符不是a
,它将给出一个编译错误:
main.cpp:29:24: error: array subscript value ‘1’ is outside the bounds
of array ‘dummy’ of type ‘int [0]’
constexpr Test t = "baa"_test;
让我困惑的是,如果我将代码更改为:
int main()
{
dummy[1] = 0; //no compile error anymore
}
<>我想知道C++何时报告数组越界错误。
<代码> CONTXPRP</代码>要求编译器评估代码。而且,因为在C++抽象机的上下文中,
和g++
都选择将此设置为错误。)clang++
((size_t const*)ptr)[-1]
也就是说,在这种情况下触发编译器错误的更好方法是简单地使用静态断言:
static\u assert(p_[0]!='a',“字符串不以'a'开头”)
未定义的行为。我猜它与constepr
相关?我已经试过了,Clang(4.0和6.0)也做了同样的事情。有趣!GCC-fsantize=bounds
标志可能有用。请注意,您可以通过完美定义的行为来实现这一点;您可以分配一个char
缓冲区,确保有足够的对齐,并在构建阵列之前为正确对齐的大小\u t
留出空间。然后,您可以获取最终的数组指针,转换回char指针,偏移sizeof size\u t,并转换回存储在那里的size\u t。优化器很可能会使机器代码完全相同,就像朴素的UB解释一样。(我唯一不确定的部分是使用新的和动态大小的布局来创建一个新的数组)我之所以提到它,是因为我记得在过去看到过包含非常相似内容的库代码,这是我想要演示的一个很好的示例。但是谢谢你解释没有UB怎么做。我有点想了想,但我脑子里一点也不知道什么时候该选UB,什么时候该选UB,什么时候该选UB?那是从哪里来的?结果我错了。我刚刚检查过,根据3.27,包含UB的程序可能会被拒绝翻译,并显示诊断消息。我修改了答案,使之更准确。注意,这可能是一个错误,但也可能是一个警告。