I'll start with an example. There is such a mid() function for container classes, in particular for QVector . It allows you to get a cut from the middle of the container. In the description of the function is the following:

Returns a sub-vector of which contains elements from this vector, starting at position pos . If length is -1 (the default), all elements after pos are included; if there are less than length elements are included.

For the length, one special value -1 indicated, it is also said that if length greater than the real tail, then all remaining elements will be taken. What happens if the position is negative or greater than the actual size of the container, as well as with other negative lengths other than -1 is not clear. You have to go to the source and watch yourself:

 QContainerImplHelper::CutResult QContainerImplHelper::mid(int originalLength, int *_position, int *_length) { int &position = *_position; int &length = *_length; if (position > originalLength) return Null; if (position < 0) { if (length < 0 || length + position >= originalLength) return Full; if (length + position <= 0) return Null; length += position; position = 0; } else if (uint(length) > uint(originalLength - position)) { length = originalLength - position; } if (position == 0 && length == originalLength) return Full; return length > 0 ? Subset : Empty; } 

All situations have already been processed here and, therefore, we really should not get a real way out of the array, and as a consequence of UB. But why is this not indicated in the “top” function description in the help center? It may be assumed that for some "specially optimized" cases these checks will not be? Or is Qt first of all the maximum fool protection?

So far, it turns out that if a person comes to the Qt world from pure C ++, he will hang up additional argument checks before the call, so as not to catch UB, although these checks are already inside the library. Thus, wasting time on unnecessary code. And the one who, on the contrary, started with Qt when switching to pure C ++, will receive the full program of all kinds of Access Violation in runtime.

In the end, I want to understand what all the same guide in the development of code, using the library Qt. Is it possible to rely on maximum security and parameter verification always and everywhere, or still, it is worthwhile to provide manual verification in some places, since Help does not contain sufficient information?

  • Qt is a very old library full of very poorly written places. Do not expect revelations from her. - ixSci
  • @ixSci in this case, it’s rather not about "written", but about "described" places. More precisely about the reasons for the existing description. By the way, is there somewhere a list of these "poorly written places", maybe someone keeps a registry? Or is it easier to keep a list of well-written Qt places? :) - αλεχολυτ
  • Why make a list? There are bad places in all libraries; Qt, in this regard, looks more advantageous. As for the description: Qt documentation is an example to follow, but not everything is there, sometimes you need to look at the code. Fortunately it is available. In MSDN, too, there is not everything, and there is often no code either. - ixSci

1 answer 1

In my opinion, in working with Qt, as with other libraries, you must comply with the contract. That is, the correspondence of call parameters and the interpretation of return values ​​to what is written in the help (or somehow documented). For that which is not specified in the contract can be changed. When moving to, say, another version of the library.

In addition, a breach of contract can often indicate not that you know and use "undocumented features", but that there is an error in your logic. This complicates the maintenance of such a code.