[Qt-interest] Undefined behavior in QString::toStdWString() ?

Robert Hairgrove evorgriahr at hispeed.ch
Fri Dec 12 00:59:46 CET 2008


Thiago Macieira wrote:
> Robert Hairgrove wrote:
>> If str is empty, begin() also does not point to anything, AFAIK; i.e.,
>> begin() == end() in that case.
> 
> begin() == end(), but they do point somewhere.
> 
> But, in any case, even if it didn't, there's no problem because if the 
> string is empty, the toWCharArray function won't do anything.
> 
>> It seems to me that checking for length() == 0, which is done only in
>> case the compiler is MSVC 2005, should be done in any case.
> 

Thank you for your reply. I just tried doing something similar to what 
is done in the function QString::toStdWString, i.e.:

=== code starts ===
#include <iostream>
#include <ostream>
#include <string>

int main()
{
   std::string s;
   std::string::iterator it = s.end();
   char * x = &(*(it));
   std::cout << reinterpret_cast<unsigned int>(x) << std::endl;
}
=== code ends ===

Everything compiles and seems to run normally, regardless of whether I 
use begin() or end(). However, I just wonder how safe this is? Both g++ 
and MSVC 7.1 accept the following just as well and output the expected 
(??) value of "0":

int main()
{
   char * y = 0;
   char * x = &(*y);
   std::cout << reinterpret_cast<unsigned int>(x) << std::endl;
}

In the first case, the output is some other number, so I suppose we 
don't really dereference a null pointer which would obviously invoke UB. 
However, according to the Forward Iterator requirements of the C++ 
standard (24.1.3, Table 74), the unary operator* has a precondition that 
its operand is dereferenceable, and states that
   "a == b implies that *a == *b"

So by this definition, dereferencing begin() on an empty string should 
be just as much of a no-no as dereferencing end(), is it not? I know 
that we probably won't get into trouble as long as we don't actually 
assign to it, but UB is UB...



More information about the Qt-interest-old mailing list