In this case, C ++ will check the bounds of the array at compile time?

Inspired by the idea of ​​a “ C ++ HTML template engine that uses compilation of HTML parsing ”, I am trying to write a sample class to check if the first char in line 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; } 

Works well (GCC7.1 on Ubuntu). If the first char is not a , it will give a compilation error:

 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; 

What confused me was if I changed the code to:

 int main() { dummy[1] = 0; //no compile error anymore } 

I am wondering when C ++ reports an array error outside the bounds.

+5
source share
1 answer

constexpr requires the compiler to evaluate the code. And, since in the context of an abstract C ++ machine, the behavior of dummy[1] is undefined, it should emit diagnostics. (This may be a warning or an error. However, for both g++ and clang++ select the error.)

However, just because dummy[1] is undefined behavior in the context of a C ++ abstract machine does not mean that something else does not define the behavior. This means that the code does not have to be rejected (if the compiler itself should not use it). This is just undefined behavior, not a mistake.

For example, compiler writers will use access to the boundaries of border arrays, and since they write the compiler, they can ensure that the behavior that occurs is desirable. A good example is array memory management, where the returned pointer is usually one word preceding the beginning of the allocated memory (since the size should also be allocated.) Therefore, when the compiler writer needs to read the size that he or she can make ((size_t const*)ptr)[-1] .

If we say that the best way to cause a compiler error in this case is to simply use static assert: static_assert(p_[0]!='a', "String does not begin with 'a'.") .

+3
source

Source: https://habr.com/ru/post/1270538/


All Articles