[devel] [APT PATCH] rpmSingle{Pkg, Src}Index::ArchiveURI(): avoid cases with undefined behavior
Ivan Zakharyaschev
imz на altlinux.org
Вт Фев 18 04:55:33 MSK 2020
On Mon, 17 Feb 2020, Ivan Zakharyaschev wrote:
>
> On Sun, 16 Feb 2020, Dmitry V. Levin wrote:
>
> > On Sun, Feb 16, 2020 at 04:09:14AM +0300, Ivan Zakharyaschev wrote:
>
> > > * File.length() < 2. Since File was a non-const string,
> > > File[File.length()] might be UB before C++11. Now, File is const, and
> > > it is guaranteed that File[File.length()] == 0.
> >
> > We can safely assume C++11, but I don't think we have an UB here even
> > before C++11.
>
> FWIW, after thinkng over the corresponding piece[1] which you cited (a
> third time):
>
> [1]: https://en.cppreference.com/w/cpp/string/basic_string/operator_at
>
> > reference operator[]( size_type pos );(1)
> > const_reference operator[]( size_type pos ) const;(2)
> >
> > Returns a reference to the character at specified location pos. [...]
> >
> > 1) If pos == size(), the behavior is undefined.
> > 2) If pos == size(), a reference to the character with value CharT()
> > (the null character) is returned.
> >
> > (until C++11)
>
> I can see a reason to agree with you: whether the object is const might
> not be the thing that determines which variant of the method is used.
>
> The question was whether variant (1) or (2) was used here in
> (File[1] == '/') if File was not const.
>
> (If (1) is used, it is stated that it would be UB until C++11; if (2),
> then not.)
>
> I doubt I'm able remember all the details of how the choice is done
> between overloaded methods, but common sense gives a hint: only methods
> labelled "const" can be invoked on a const object whereas all methods
> (both labelled "const" and not) can be invoked on a non-const object.
>
> Under this view, we see that the methods labelled "const" are equally well
> available for non-const objects. So, another factor must make the choice
> between (1) and (2).
>
> And here the only remaining factor seems to be the expected result
> type/constness in the expression where it is used (although that might
> seem weird because of its "implicitness"): a const reference will do for
> (_ == '/'), so (2) is probably inferred under the hood as the variant to
> use here.
>
> Of course, I might be wrong in my reasoning, and it's not quite important
> for this place in APT's code anymore anyway (as there was another reason
> to rewrite it), but I wished to share this curiosity regarding how the
> meaning of C++ code can be non-obvious to mere mortals (like me).
No, this reasoning must have been false, as pointed out by darktemplar@,
by giving a link to the following explanations.
https://stackoverflow.com/a/164208/94687 :
The compiler does not take into account how you are using the return value
in its determination; that's not part of the rules. It doesn't know if
you're doing
std::string name = b->Name();
or
b->Name() = "me";
It has to choose the version that works in both cases.
https://stackoverflow.com/a/164130/94687 :
> There it noted that member functions may be overloaded merely by their
> const attribute. In those cases, the compiler will use the member function
> matching most closely the const-qualification of the object
--
Best regards,
Ivan
Подробная информация о списке рассылки Devel