From: Bo Persson on
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
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
"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
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
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! ]