Re: [llvm-dev] [isocpp-parallel] Proposal for new memory_order_consume definition
No, you really don't need undefined behavior in the standard in order to enable bug-finding. The standard could've (and still could...) make signed integer overflow "implementation-defined" rather than "undefined". Compilers would thus be required to have *some documented meaning* for it (e.g. wrap 2's-complement, wrap 1's-complement, saturate to min/max, trap, or whatever...), but must not have the current "Anything goes! I can set your cat on fire if the optimizer feels like it today!" behavior. Such a change to the standard would not reduce any ability to do error checking, as compilers that want to be helpful could perfectly-well define it to trap at runtime when given certain compiler flags, and perfectly well warn you of your dependence upon unportable implementation-defined behavior (or, that your program is going to trap), at build-time. [Sending again as a plain-text email, since a bunch of mailing lists apparently hate on multipart messages that even contain a text/html part...] On Mon, Feb 29, 2016 at 2:38 PM, Lawrence Crowl via llvm-dev wrote: > On 2/28/16, Linus Torvalds wrote: >> The fact is, undefined compiler behavior is never a good idea. Not for >> serious projects. > > Actually, undefined behavior is essential for serious projects, but > not for the reasons mentioned. > > If the language has no undefined behavior, then from the compiler's view, > there is no such thing as a bad program. All programs will compile and > enter functional debug (possibly after shipping to customer). On the > other hand, a language with undefined behavior makes it possible for > compilers (and their run-time support) to identify a program as wrong. > > The problem with the latest spate of compiler optimizations was not the > optimization, but the lack of warnings about exploiting undefined behavior. > > -- > Lawrence Crowl > ___ > LLVM Developers mailing list > llvm-...@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Long-term plan for C++98/C++11 incompatibility
I just noted at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561 (due to std::list), that it's currently impossible to use any C++11-compiled code in a program which also uses any C++98 code, even if the two pieces of code never actually touch each other or share objects. After I noted that, paolo and redi then told me it was in fact already broken long before, due to numerous other ODR violations in libstdc++ when compiled in the different modes. I just hadn't noticed. D'oh. So, it's actually rather tricky to correctly use --std=c++0x. While it *looks* like you can just compile your own code with that flag (it appears to work), it seems that it doesn't actually work, and is expected to work less and less as time goes on. (Presumably std::string will be made non-refcounting soon to be C++11-conformant, breaking interoperability much more.) I guess to start, it would have been nice if there was a big warning on http://gcc.gnu.org/projects/cxx0x.html telling me not to use c++0x mode unless there are no objects compiled with c++98 linked into the same executable. I know I'm not the only one who didn't realize how broken it was to do that. I also suspect there's plenty of other people who still don't know that, and will be unpleasantly surprised by mysterious seg-faults soon. I completely understand that the current support in GCC is still experimental, and I should expect nothing from it. But what I'd really like to have a handle on is what things are supposed to look like when C++11 support is no longer experimental. What's the planned final state of affairs? * Will STL-using code compiled with -std=c++98 and -std=c++11 remain incompatible forever, or only until it's no longer experimental? * If so, will version namespaces be used to give c++98 std::* and c++11 std::* non-conflicting symbols eventually, so that at least the same program can load two shared libs that only use the STL internally and not in their interfaces? * For that matter, are the c++98 and c++11 languages even link-compatible without STL? Is the incompatibility only due to the #ifdefs in the STL headers or is it more fundamental than that? * How are binary linux distributions expected to support c++11 programs? (in that they'll need to eventually provide shared libraries to link against which a c++11-compiled binary can use). It seems to me that it can't be done like previous ABI transitions (just recompile the whole world with the new ABI, boom done), since C++11 is not source compatible with c++98. So should a distro compile two copies of all C++ libraries, one for C++11 and one for C++98? Then, I suppose people will have to change e.g. "-lPocoNet" to "-lPocoNetCXX11" in their link lines? Or maybe ld/gcc will be modified to automatically choose a different library search path, based on the compilation mode? Or will there be a giant flag day after most projects compile can compile in both c++11 and c++98, where c++98 support is removed, and everything is compiled in c++11 from then on? (but then, how would we get there: all developers would have to compile their entire dependent set of libraries from scratch themselves to test their code, I guess.) I hope the experts here have a better idea of how this is all going to work that I do. IMO it would be best if if the new ABI could be enabled separately from the C++11 language, so that you *could* compile everything with the new ABI, and have c++98 and c++11 code interoperate. But I have no clue if that's even remotely feasible. Thanks for any insight! This seems to be a lot more complex than I naively thought the transition was going to be.
Re: C++98/C++11 ABI compatibility for gcc-4.7
You've missed at least one ABI incompatibility in GCC 4.7 and later, as demonstrated in real life by (at least) libboost_python, and distilled into this test case. At least these bug reports are probably caused by this ABI incompatibility: https://svn.boost.org/trac/boost/ticket/6919 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 https://svn.boost.org/trac/boost/ticket/6895 As I've said before, I really wish GCC devs would take the ABI incompatibility problem more seriously. Lots of users have already started using -std=c++0x mode, and have absolutely no idea that it's completely unsafe to do so on a normal linux distro, linking against regular C++ libraries that are not compiled with a) c++11 enabled, and b) the exact same version of GCC. I understand that the ABI changes generally cannot be avoided, but a lot of pain for a lot of people could be avoided by making things fail obviously with a link error, instead of sometimes, arbitrarily, if you're lucky, you'll get a segfault at runtime. test1.cpp #include std::pair execute() { return std::make_pair(0, 1); } test2.cpp #include #include std::pair execute(); int main() { std::pair result = execute(); printf("%d %d\n", result.first, result.second); } test.sh #!/bin/sh CC="g++-4.7 -O1" $CC -std=c++03 -o test_cxx03.o -c test.cpp $CC -std=c++0x -o test_cxx11.o -c test.cpp $CC -std=c++03 -o test2_cxx03.o -c test2.cpp $CC -std=c++0x -o test2_cxx11.o -c test2.cpp $CC -o test test_cxx03.o test2_cxx03.o; ./test $CC -o test test_cxx11.o test2_cxx11.o; ./test $CC -o test test_cxx03.o test2_cxx11.o; ./test $CC -o test test_cxx11.o test2_cxx03.o; ./test output 0 1 0 1 -1757034448 32767 Segmentation fault
Re: C++98/C++11 ABI compatibility for gcc-4.7
> On 31 May 2012 22:35, James Y Knight wrote: >> I understand that the ABI changes generally cannot be avoided, but a lot >> of pain for a lot of people could be avoided by making things fail >> obviously with a link error, instead of sometimes, arbitrarily, if >> you're >> lucky, you'll get a segfault at runtime. > > Do you have any suggestions for how to do that? Sure, I have a suggestion. I'm not an expert here, so perhaps it has issues, but...here goes anyways. Inline namespaces could be used in C++11 mode. libstdc++ would include two copies of all affected objects: one compiled in C++03 mode with the C++03 names, and one compiled in C++11 mode with the C++11 names. Classes should be given a new name every time they change incompatibly in C++11 mode, which is probably every release for a number of classes. For the C++11-specific symbols that'd be exported from libstdc++ when doing this, you'd have to decide whether to let them appear and disappear every GCC release without a pretense of backward compatibility (c++11 mode being experimental, after all), or, to preserve enough of the old class definitions internally to the library that the old symbols with the old behavior can continue being exported, even when the classes have been modified (nicer for users, but harder on implementors). Also helpful, even before a technical solution has been created, would be for the incompatibility to mentioned prominently in the GCC manual when describing the -std=c++0x/11 option, and in big letters on http://gcc.gnu.org/projects/cxx0x.html. As I said, pretty much nobody even knows that this is a problem, unless they follow the GCC mailing lists or until they run into it independently and figure out what's happened. Since GCC 4.7 implements a fair portion of C++11, and C++11 is starting to gain a lot of traction, I'd expect these issues to start coming up more and more frequently, as more and more people start compiling their programs in C++11 mode.
Re: C++98/C++11 ABI compatibility for gcc-4.7
> It seems to be an inadvertent incompatibility caused by the > interaction of a libstdc++ workaround for a bug and g++ behaviour that > may not have been known to the libstdc++ devs, so not something that > could have been prevented by making it a linker error, because noone > knew it was even broken. Testing and reporting bugs and analysing the > problem should lead to it being fixed. I think the problem was GCC > devs not knowing the problem existed, rather than not taking it > seriously. Whether or not this particular incompatibility was intended or not, the point remains. You cannot say that GCC devs are taking the C++11 binary incompatibility issue seriously while: a) there exist serious ABI incompatibilities between the modes. b) there is essentially no notice to users about the problem (and lots of users already brokenly compiling in C++11 mode!) c) there are no recommendations or plans for how users and distros are expected to deal with the issue. I am happy to see that Matthias has also recently noted this issue from the point of view of a distribution. But I'm *quite* surprised to see that even now it is apparently a surprise to some on this very list that there is such an incompatibility! When I noted the std::list incompatibility back last October when it was introduced (on http://gcc.gnu.org/PR49561), the response was quite clear that there is no expectation of compatibility between the modes, and never was. When I tried to ask some of these same questions last November (in the "Long-term plan for C++98/C++11 incompatibility" thread), the answer I heard there seemed to me to be ~"distros should just provide two sets of libraries, not our problem". IMO, at the /very least/, libstdc++ should go ahead and change std::string to be the new implementation. Once std::string is ABI-incompatible between the modes, there's basically no chance that anyone would think that linking things together from the two modes is a good thing to try, for more than a couple minutes.
Re: [libc-coord] Add new ABI '__memcmpeq()' to libc
Wouldn't it be far simpler to just un-deprecate bcmp? On Thu, Sep 16, 2021 at 1:04 PM Noah Goldstein wrote: > Hi All, > > This is a proposal for a new interface to be supported by libc. > > The new interface is the same as the old 'bcmp()' routine. Essentially > the goal of this proposal is to add a reserved namespace for a new > function, '__memcmpeq()', which shares the same behavior as the old > 'bcmp()'. > > Interface > > int __memcmpeq(void const * s1, const void * s2, size_t n) > > > Description > > The '__memcmpeq()' function would compare the two byte sequences 's1' > and 's2', each of length 'n'. If the two byte sequences are equal, the > return would be zero. Otherwise it would return some non-zero > value. 'memcmp()' is a valid implementation of '__memcmpeq()'. > > > Use Case > > 1. The goal is that '__memcmpeq()' will be usable as an optimization >by compilers if a program uses the return value of 'memcmp()' as a >boolean. For example: > > > void foo(const void* s1, const void* s2, size_t n) > { > if (!memcmp(s1, s2, n)) { > printf("memcmp can be optimized to __memcmpeq in this use case\n"); > } > } > > > - In the above case '__memcmpeq()' could be used instead. Due to the > simpler constraints on the return value of '__memcmpeq()', it will > be able to be implemented more optimally for this case than > 'memcmp()'. If there is no separately optimized version of > '__memcmpeq()' can alias 'memcmp()' and thus be at least equally as > fast. > > 2. Possibly use cases in security as the runtime of the function will >be *more* oblivious to the byte sequences being compared. > > > Argument Specifications > > 1. 's1' > - All 'n' bytes in the byte sequence starting at 's1' and ending > at, but not including, 's1 + n' must be accessible memory. There > are no guarantees about the order the sequence will be > traversed. > 2. 's2' > - All 'n' bytes in the byte sequence starting at 's2' and ending > at, but not including, 's2 + n' must be accessible memory. There > are no guarantees about the order the sequence will be > traversed. > 3. 'n' > - 'n' may be any value that does not violate the specifications on > 's1' and 's2'. > > If any of the argument specifications are violated there are no > guarantees about the behavior of the interface. > > > Return Value Specification > > If the byte sequences starting at 's1' and 's2' are equals the > function will return zero. Otherwise the function will return a > non-zero value. > > Equality between the byte sequences starting at 's1' and 's2' is > defined as follows: > > 1. If 'n' is zero the two sequences are zero. > 2. If 'n' is non-zero then for all 'i' in range [0, n) the byte at >offset 'i' of 's1' equals the byte at offset 'i' in 's2'. > > For a simple C implementation of '__memcmpeq()' could be as follows: > > > int __memcmpeq(const void* s1, const void* s2, size_t n) > { > int ret; > size_t i; > const char *s1c, *s2c; > s1c = (const char*)s1; > s2c = (const char*)s2; > for (i = 0, ret = 0; ret == 0 && i < n; ++i) { > ret = s1c[i] - s2c[i] > } > return ret; > } > > > Notes > > This interface is essentially old 'bcmp()' and 'memcmp()' will always > be a valid implementation of '__memcmpeq()'. > > > ABI vs API > > This proposal is for '__memcmpeq()' as a new ABI. As an ABI > '__memcmpeq()' will have value, as using the return value of > 'memcmp()' is quite idiomatic in C code. > > It is, however, possible that this would also be useful as a new API > as well. Especially if there are likely use cases where the compiler > would be unable to prove that '__memcmpeq()' would be a valid > replacement for 'memcmp()'. > > > Further Options > > If this proposal is received positively, libc could also add > interfaces for '__streq()', '__strneq()', '__wcseq()' and '__wcsneq()' > which similarly would loosen return value restrictions on 'strcmp()', > 'strncmp()', 'wcscmp()' and 'wcsncmp()' respectively. > > Best, > Noah >
Re: [libc-coord] Add new ABI '__memcmpeq()' to libc
On Thu, Sep 16, 2021 at 5:50 PM enh wrote: > plus testing for _equality_ can (as mentioned earlier) have slightly > different properties from the three-way comparator behavior of > bcmp()/memcmp(). > Per spec, bcmp is not a three-way comparison, it is an equality comparison with exactly the same semantics as proposed for __memcmpeq. Glibc currently implements bcmp as an alias to memcmp -- which is valid, but provides more than just the boolean equality semantics. There was concern raised that modifying that might break existing binaries. However, this concern can be easily addressed in the same way glibc typically addresses such compatibility concerns: creating a new symbol-version for the new bcmp implementation, with the previous bcmp symbol-version remaining as a memcmp alias. > On Thu, Sep 16, 2021 at 2:43 PM Joseph Myers > wrote: > >> On Thu, 16 Sep 2021, James Y Knight wrote: >> >> > Wouldn't it be far simpler to just un-deprecate bcmp? >> >> The aim is to have something to which calls can be generated in all >> standards modes. bcmp has never been part of ISO C; there's nothing to >> undeprecate there. > > OK, I can see that. I suppose that strict ISO C compatibility could be important to someone. :)