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 ------------------------------------------------------------------------------ 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
