Re: [llvm-dev] [isocpp-parallel] Proposal for new memory_order_consume definition

2016-02-29 Thread James Y Knight
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

2011-10-07 Thread James Y Knight
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

2012-05-31 Thread James Y Knight
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

2012-05-31 Thread James Y Knight
> 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

2012-06-15 Thread James Y Knight
> 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

2021-09-16 Thread James Y Knight via Gcc
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

2021-09-17 Thread James Y Knight via Gcc
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. :)