From: Bo Persson on 29 Nov 2006 18:22 Lourens Veen wrote: > > But the UTF-8 CPP library could just as well have been written if > std::string was a built-in type rather than part of the standard > library. > > This whole discussion came about because there was a claim that > having types in the library is better, because the user can extend > them. If the types are built-in, then the compiler needs to be > changed, which the user generally can't or won't do. The other problem is that if we prove that efficient implementations can only be provided for built-in types. That would completely pull the rug from under C++, which relies heavily on a standard library. If we cannot write efficient libraries for strings, or vectors, complex numbers, or whatever, what is the use of trying at all? Then ALL types have to be implemented by the compiler writer. Is that the case?? Bo Persson -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: David Abrahams on 29 Nov 2006 21:52 Walter Bright <walter(a)digitalmars-nospamm.com> writes: > David Abrahams wrote: > >> BTW, string literals would be a builtin feature, there's no question >> about *that*. > > Ok, but that leaves open the question of what builtin type would the > builtin literal have? "stringliteral?" I don't care whether string is built in as you seem to be implying; I care that they are in all respects (other than perhaps literal syntax) a type like any other type I can define myself. In other words, this isn't about strings; it's about the capabilities of UDTs. -- Dave Abrahams Boost Consulting www.boost-consulting.com [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: David Abrahams on 29 Nov 2006 21:52 "Peter Dimov" <pdimov(a)gmail.com> writes: > Walter Bright wrote: > >> Here's what Digital Mars C++ does, which implements C99 complex numbers: >> >> ------------------ program ------------------ >> #include <complex.h> >> >> complex long double f( complex long double c ) >> { >> return c; >> } >> ------------------- asm --------------------------- >> ?f@@YA_W_W@Z: >> fld tbyte ptr 4[ESP] >> fld tbyte ptr 0Eh[ESP] >> ret >> -------------------------------------------------- > > So your point is that having complex as a built-in allows you to define > an ABI that returns it in ST0:ST1 (but you still pass it on the stack.) > I admit that it's unlikely for any ABI to return UDTs in registers. KCC used to do that before Intel killed it. -- Dave Abrahams Boost Consulting www.boost-consulting.com [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Walter Bright on 30 Nov 2006 01:11 Nevin :-] Liber wrote: > So what is it about C++ that is stopping you from applying the > optimization you use for the intrinsic complex to std::complex (and > then, in general, to objects that have a similar form to std::complex)? Having constructors causes problems for it. Even though indirection can often be removed by the optimizer, the decisions about how returns are done are made in the parsing stage, because it affects how constructors are set up to get the return type built on the caller's stack. The optimizer/code generator really only see the C-like result of all that. If it was so easy to do otherwise, the compilers would be doing it. None of them do. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: James Kanze on 30 Nov 2006 10:02
Andrei Alexandrescu (See Website For Email) wrote: > Andrei Alexandrescu (See Website For Email) wrote: > > James Kanze wrote: > >> Andrei Alexandrescu (See Website For Email) wrote: > >>> That's simply wrong. Java does not check thread safety > >>> statically, yet is able to define behavior of even incorrect > >>> multithreaded code. > >> Writing to a double while another thread is reading it is > >> undefined behavior in Java. > > I've ran a number of searches for that ("java undefined behavior > > double", "java undefined behavior threads double" etc.), no avail. I'd > > be glad if you provided a reference. Thanks! > > Maybe (also) we're using slightly different definitions for undefined > > behavior? > I am still waiting for a response on this issue, or a retraction of the > initial statement. Sorry, I missed your previous posting. (I've not been following this thread too closely, since D is not a topic which interests me much.) I don't know quite what different definitions we could be using. Undefined behavior occurs when the language specification places no definition on the behavior. I don't know how you can easily search for it, because it is the absence of a definition. Java (and most other languages) don't use the term, or even specify explicitely what they don't specify. So the reponse is rather the opposite: unless you can find some statement in the language specification which defines this behavior, it is undefined behavior. Actually, I think there are even more cases, involving multiple writes to different variables. But the case of double or long is flagrant, since the language specification does not require the writes to be atomic. In practice, of course, Java runs on hardware, and it is always tributary to what the hardware does. And the hardware itself has undefined behavior when there are multiple writes and reads from different threads, with no intervening fence or membar or whatever instructions. Putting such instructions around each and every access would slow the machine down too much, so they accept undefined behavior. > This is relevant to C++ in the following way. When the C++ thread > standardization process started, it was assumed that the Java memory > model ensures well-defined programs even when they do have races. The > committee decided (correctly IMHO) to depart from that model for > efficiency reasons, leaving the behavior of certain programs undefined. > My current understanding is that races on longs and doubles could > produce undefined longs and doubles being read, but not undefined programs. What's the difference? Especially in the case of double, where the undefined double might be a signaling NaN? In practice, the intent is clearly to allow reads and writes to occur without intervening synchronization. And the hardware offers very few guarantees in such cases. > Now, if Java does allow programs with undefined behavior, that would > quite change the "golden standards" in terms of safety. Well, there's a certain sense in which all languages have "undefined behavior". The C standard (and I think C++) speak of undefined behavior if the program exceeds the resource limits. One generally thinks of this in terms of memory, or stack overflow, or such, and Java does define behavior in such cases. But on the machines I use, there are other essential resources---most of the chips require 5 volts, -/- 10%, or something like that. If the power supply voltage drops, they start behaving in a random fashion. Insufficient voltage (a resource) results in undefined behavior, and there's nothing the language specification can do to change it. Obviously, I don't think it's quite the sort of thing we have in mind in general. But I mention it to relativize the importance of no undefined behavior. Gratious undefined behavior (e.g. that due to modifying the same variable twice without an intervening sequence point) is just plain stupid---there's no excuse for it. IMHO, Java does an excellent job in this respect, and is a good model for this type of undefined behavior. And C++ is a disaster in this regard, and seriously needs improvement. Intentional undefined behavior, such as that resulting from the use of reinterpret_cast, is necessary if you want to support low level programming---there's no point in comparing C++ with Java here, because Java intentionally excludes these types of applications. Finally, there is undefined behavior simply because current hardware doesn't permit avoiding it, at least not without outrageoulys excessive costs. You can't (reasonably) say that an implementation is not conforming unless it has a back-up power supply, and in a general purpose language, you cannot reasonably require defined behavior if two threads start modifying the same variable at the same time. At any rate, I think any discussion concerning undefined behavior is rather senseless unless it keeps these distinctions in mind. I'm rather glad that C++ has the undefined behavior which results from abusing a reinterpret_cast; it's useful, even necessary for certain types of applications, and reinterpret_cast is easily grepped for, so I can avoid it (provided the compiler complains when a C style cast or a function style cast resolves to a reinterpret_cast) when it's not necessary. And for better or for worse, I think we're stuck with undefined behavior (at least at the program level) when threads are involved. But I would definitly support reducing or even completely eliminating undefined behavior of the first sort. -- James Kanze (GABI Software) email:james.kanze(a)gmail.com Conseils en informatique orient�e objet/ Beratung in objektorientierter Datenverarbeitung 9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34 -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |