hgm wrote:wgarvin wrote:Ah, I think I understand your confusion. The Apple code is probably in the library function, and only gets invoked if that library function is actually called. If the compiler "got smart" and did something else on the front of that (like the optimizations Ronald described, and which I am talking about in the last few posts) then Apple's test never gets to happen. I think that result was shown in the test results that were posted in this thread yesterday, unless I mis-read them?
The optimizations described by Roland were
not on an Apple, right? So I think it is those two cases that are in danger of getting confused. They are also only vaguely related, because in Bob's example the strlen() was known at compile time. It did not involve the method described by Ronald. Marcel described that. The 'trick' it used to eliminate the strcpy was by inlining quadword moves. This trick would always work, btw, irrespective of overlap. So no UB assumption is needed to make it safe. But it was only applied to the case of moving to higher addresses. Not sure why that was (alignment, perhaps?).
Ah ! Thats true that the one MVK posted would still work, that's a very good point. The ones shown after that by Ronald would not. I will try to be more careful not to mix them up.
hgm wrote:
So either I am still just as confused as I was, or I am (still) right.
Anyway, I'm not sure why you think its an invalid point that the compiler's optimization becomes unsafe if you want to make this specification change to the API of strcpy.
Because I never proposed the API should be changed in a way that would make that optimization unsafe. What I want changed is the 'nasal demons clause', that would give compiler writers completely free hand in inflicting maximum unnecessary damage to their victims, abusing a freedom that was only given to them for the purpose of making some optimization possible. The strcpy UB was established for removing the need to test for overlap. If they test for overlap anyway, it should be forbidden to do any nastiness, as they obviously do.
K, hold on there. The library function apparently tests for overlap, and aborts. I argued already (or actually, Linus and then bob argued already) that the test is cheap and providing memmove instead of abort would cost "effectively" nothing, and be more user-friendly. But there's also the compiler's treatment of the intrinsic function to consider, not just what the library code does if control ever reaches it. And some compilers, as Ronald has shown, do clever optimizations there which won't be possible if you redefine that API to say the copying has to work even with overlapping strings. So thats an inevitable consequence of "forbidding them to do nastiness" (or, "changing the API specification of strcpy" as I think I put it before). Maybe its worth it--hell, it probably is. But contrary to what bob claimed, the price is not zero. Maybe currently Apple doesn't do that optimization, but if they follow the suggestion to support overlapping copies then
they won't ever be able to do it the way GCC can do it today.
hgm wrote:And that applies even more to integer overflow. Common sense would of course make this self-evident, but it seems that common sense is lacking entirely in some circles (or perhaps overruled by commercial interests), so that i should be enforced.
You could change the code of the library function to permit overlapping copies, but then the compiler either needs to disable these optimizations entirely, or generate code to perform an overlap test before the inlined small-and-clever intrinsic code it wants to generate (which would significantly complicate things and would add some additional runtime cost). So that's my point. You guys say there is no cost to getting rid of the "no overlaps" restriction, and I'm saying that this is part of the cost, lost or degraded optimization opportunities.
The overlap test that Apple performs inside their function probably doesn't cost too much... if its anything like the glibc memcpy (e.g. if perhaps it is implemented by "strlen then memcpy"), then they already want to dispatch to one of several different implementations based on things like length and pointer alignment. For the memcpy case, that was why Linus believed it could be converted into memmove semantics "free of charge": the necessary test-and-dispatch costs were basically already being paid by that implementation. But even if Apple is paying a small extra cost for that test, at least it is revealing bugs in programs that might have otherwise gone undetected for a long time, and caused those programs to mysteriously corrupt their data or otherwise produce incorrect results.
That is a lousy argument. If the purpose was to detect bugs, they could have restricted this to some debugging mode. There is no need to burden correct and debugged code with this extra overhead.
Maybe they didn't think enough people would run in the debugging mode? They might have wanted programmers to always have the info, and just underestimated how many compiled binaries and source programs were out there in the wild, that relied on the UB. Maybe after the outcry they will reevaluate, as the glibc guys did (eventually) with the memcpy changes. I admit I was surprised to find out there were so many broken programs out there. I mean, strcpy and memcpy are some of the most basic standard library functions that
every C and C++ programmer should know how to use correctly. Its shocking that some people think overlapping memcpy is supposed to work correctly, I don't really understand how they can program for years and years in a language like C without ever learning how it works.