2011/11/5 K. Frank <[email protected]>: > Hello Kai! > > On Sat, Nov 5, 2011 at 10:31 AM, Kai Tietz <[email protected]> wrote: >> 2011/11/5 K. Frank <[email protected]>: >>> Hi Kai! >>> >>> Thanks for your response. >>> >>> I don't follow what you are saying -- please see my comments at >>> the bottom. >>> >>> On Sat, Nov 5, 2011 at 4:29 AM, Kai Tietz <[email protected]> wrote: >>>> 2011/11/5 K. Frank <[email protected]>: >>>>> Hello List (and Ruben)! >>>>> >>>>> I think I have come across a bug in Ruben's 64-bit 4.7.0 build, otherwise >>>>> known as "The Mighty Ruben's Wacky Build" ("TMRWB") (TM). >>>>> ... >>>>> I can also explain why I think this is a real bug, and not incorrect code >>>>> invoking "undefined behavior." >>> >>> A quick comment on this. Kai raises the issue of signed / unsigned >>> conversions (because std::streamsize is signed). I've raised the issue >>> of narrower (32-bit) / wider (64-bit) unsigned conversions. As I explain >>> below, I don't think std::streamsize enters into this, but even if it did, I >>> still believe that the compiler is not behaving properly. >>> >>> As I read the standard, neither the signed / unsigned nor the narrower / >>> wider conversions invoke undefined behavior. Narrower / wider integral >>> are, I believe, well specified by the standard. I believe that signed / >>> unsigned integral conversions can be implementation-defined (based >>> on how the implementation / hardware represents negative integers, >>> and how it implements sign extension), but not undefined. >>> >>> No matter how the conversions are implemented, as I look at the code, >>> I think that the behavior should be well defined and the function should >>> either enter an infinite loop or run correctly. Exiting the loop apparently >>> early (no matter what the conversions are) seems to me to be a compiler >>> bug. >>> >>>>> ... >>>>> Thanks for anyone's thoughts. >>>>> >>>>> K. Frank >>>> >>>> Hmm, this looks to me indeed as logical wrong code, but by different >>>> reason as you are assuming. The underlying issue here is that >>>> streamsize is derived from ptrdiff_t, which is a signed type. But you >>>> are using here an 'unsigned'. >>>> The expanding rule from unsigned to signed with higher precision >>>> remains unsigned valued. For 32-bit we have here for both types same >>>> precision, and therefore indeed the sign check is done as intended. >>> >>> Here's what I don't understand about your comment: In the code above, >>> std::streamsize is used explicitly in two places: >>> >>> virtual std::streamsize xsputn (const char *p, std::streamsize n) { >>> >>> as the return type of xsputn, and as the type of the argument n. It is >>> also used implicitly, if you will, in the return statement of xsputn: >>> >>> return n; >>> >>> But n is never modified in the code, and is only used, as I understand it, >>> in a fully legal pointer-arithmetic expression: >>> >>> m_string.append (p, p + n); >>> >>> (p is a char*). >>> >>> So I just don't see any signed / unsigned mismatch between std::streamsize >>> and any other integral type. >>> >>>> If you are using here instead of 'unsigned' a 'signed' n, everything >>>> works as expected. >>> >>> I don't follow what the concrete change to the code would be. I'm happy >>> to make such a change and see if it fixes the problem, but I don't see >>> what specific change you are proposing. >>> >>> If you mean changing the type of the argument n to be unsigned: >>> >>> virtual std::streamsize xsputn (const char *p, unsigned n) { >>> >>> I don't think that I would be allowed to do that because the signature of >>> xsputn is defined by the iostream library (and hence by the standard). >>> >>> (Of course, when I say I think there is an error in the compiler, I mean >>> the whole compiler / library package. The compiler could be okay, but >>> there could be an error in the library code. To clarify, I do believe that >>> the compiler is generating incorrect code, but if a coding error in the >>> library were invoking undefined behavior, the compiler would technically >>> be within its rights to do so.) >>> >>>> Regards, >>>> Kai >>> >>> Further thoughts would be greatly appreciated. >> >> See, if I have a 32-bit unsigned scalar integer and I convert it into >> a 64-bit signed integer conversion, it is wrong believe that a >> sign-conversion is done here. The unsigned 32-bit integer scalar fits >> into value-range of the 64-bit signed integer scalar. So result of >> widen cast remains unsigned. As by rule, always for a comparison of >> X == Y - where X has 32-bit width, and Y has 64-bit width - value gets >> promoted to wider-scalar width for comparision, we get into your >> described behavior. >> >> so the comparsion X == -1LL can be never true. And this is what you >> are actually try do here. As X gets promoted for value 0xfffffffff to >> 0xffffffffLL and not as you trying to suggest to 0xffffffffffffffffLL. > > I agree with this analysis. Yes, X == -1LL can never be true. > > But this is exactly where I see the compiler bug. If X == -1LL is never > true, then the code should enter an infinite loop. It does not. Instead, > the function seems to exit (seemingly not through its return statement), > executing the loop only once. > > Again, I agree that the code that triggers the compiler bug is logically > incorrect (in that it does not do what it was intended to do). But I still > believe that there is a compiler bug, in that the compiler does not generate > executable code that does what the standard says the well-defined (but > logically incorrect) source code should do. > >> Regards, >> Kai > > Thanks again. > > > K. Frank
Hmm, I was distracted by one typedef I saw, but missed that C++ is a mess and the really used type might be defined else-where ... The issue here is definition of npos. It has type size_type, which is indeed based on size_t. So the following line in base_string static const size_type npos = static_cast<size_type>(-1); leads to a definition of npos as 0xffffffff (due -1 is a 32-bit scalar, which gets casted to unsigned with wider-scalar). This might, or might not be a libstdc++ failure. I am no C++ guru to tell by spec. But at least it remains odd. Cheers, Kai ------------------------------------------------------------------------------ RSA(R) Conference 2012 Save $700 by Nov 18 Register now http://p.sf.net/sfu/rsa-sfdev2dev1 _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
