From: Terry G on
Here's some Undefined Behavior from the C++ Standard that I have (which
might be old) from 5.8-1.

"The behavior is undefined if the right operand is negative, or greater than

or equal to the length in bits of the promoted left operand."

Why not just define the behavior?
If the right operand is negative, then its the same as a left-shift, by the
absolute value.
If its greater than or equal to the length in bits of the promoted left
operand, then its -1 if the number was negative, otherwise 0.
I don't really care what definition is chosen. Pick something reasonable.
Then, whatever hardware instructions are available should be used to make it


[ See for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Walter Bright on
Alf P. Steinbach wrote:
> Could you be a /little bit/ more specific, please, Walter?

The trouble comes from the definition of things like log and sqrt for
complex numbers involving the sign of 0:

log(-0+0i) = -inf + i*Pi
log(0+0i) = -inf + 0i

sqrt(-x+0i) = i*sqrt(x)
sqrt(-x-0i) = -i*sqrt(x)

In other words, the sign of 0 makes a difference. When there is an
implicit 0, such as when a real or imaginary is converted to a complex,
which do you choose, -0 or +0? With a separate real type, we can
propagate through our algorithm the knowledge that it should not depend
on the sign of the (nonexistent) imaginary part. With no separate
imaginary type, we cannot correspondingly do this for the sign of the
(nonexistent) real part. We have to choose, -0 or +0, and our algorithms
lose that knowledge.

Furthermore, consider the arithmetic:
0*inf = NaN
-0*inf = NaN
But what if the 0 is an implicit 0? Then we want:
0*inf = 0
because consider multiplying
The result we expect is
(0*0 + 0*inf*i)
The result we get with implicit 0 insertion (represented by X) is
(0*0 + 0*Xi + 0*inf*i + Xi*inf*i)
(0 + 0i + NaN*i - NaN)

Without a separate imaginary type, there is no way to distinguish an
implicit 0 from an actual 0.

Here's some more reading:

[ See for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Walter Bright on
Gabriel Dos Reis wrote:
> Walter Bright <walter(a)> writes:
> | A compiler will always be more powerful than what's possible with the
> | library, for the intrinsic reason that one can code the compiler to do
> | whatever one wants to. With a library, you're stuck with what the
> | compiler chooses to make available.
> But even for a core language feature, one is also stuck with what the
> compiler writer has chosen to optimize for, i.e. make available.

That's what I said.

> For a library solution, I've seen compiler steadily improving support
> for library functionalities -- think of GCC and its support for C
> library functions. I'm afraid your speculation is countered by actual
> data.

Ok, show me a language that is so user extensible so that, say, I can
construct a library so powerful that it can exactly emulate other
computer languages. In other words, where is language X that can accept
C++, Pascal, C#, Lisp, etc., source code just be adding on a powerful
library? Steadily improving support for libraries hardly constitutes
making libraries as powerful as the compiler. That's like saying if I
climb a mountain, I'm making progress towards the moon.

> | I think that's pretty obvious, since
> no, it is not.

If you think it can be done, by all means go for it.

> | If it was possible, out of the thousands of languages
> | invented, certainly one of them would have done so?
> Some have done quite a remarkable job at it; you just need to admit
> it. That is a separate problem.

I'd love to see a language where you could, say, add the ability to
compile C++ source by adding a library.


Thank you for the convenient reference. It's a good proposal. But I
don't think it really allows for user defined literals; what it does is
just do more advanced constant folding so you can have functions (and
constructors) in constant expressions. For example, the proposal still
does not allow:

complex foo = x + 3i; // 3i is an imaginary type


Bigint x = 1238471289347189237489012734897123847182347182;

or even:
const Bigint x = Bigint("1238471289347189237489012734897123847182347182");

> | I know that D, at least, will not have user
> | defined tokens, for the reason that such would blow the legs off of
> | third party tools that process source without needing to be full blown
> | compilers.
> That is more a problem with D's design philosophy than an intrinsically
> linguistic issue.

It's hardly unique to D. C++ doesn't allow user defined tokens, either
(and neither does your C++ extension proposal). I know of no successful
computer language that does. I don't even know of any computer language
that does.

> | I don't think (2) can ever happen with C++, for the reason that it's
> | very hard to see how user defined syntax could ever be retrofitted in to
> | a language that is already the hardest language in existence to parse
> | (by a wide margin).
> I don't think your categorization of (2) is adequate. C++ has been
> offering (3) for more than 2 decades now.

It's very limited support for (3). There is no, for example, support for
user defined name lookup semantics. (And there shouldn't be!)

> There are several ways of
> doing (2) without necessarily having user defined tokens.

I separated out the issue of user defined syntax (1) from user defined
tokens (2).

> One of them is to allow users to attach their meaning to tokens.

I foresee a great future for new meanings for the 'static' keyword <g>.

[ See for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Walter Bright on
Jakob Bieling wrote:
> Walter Bright wrote:
>> But I do have a couple challenges for you <g>.
>> 2) Extend std::string to support strings with embedded 0's.
> Doesn't std::string support exactly that by default?

Theoretically it does. The problems come about when one tries to make a
reasonable implementation that is able to also deal with 0 terminated
strings, which std::string must.

[ See for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Gabriel Dos Reis wrote:
> "Greg Herlihy" <greghe(a)> writes:

> [...]

> | Hasn't anyone ever wondered how exactly the C++
> | Standard is able to find so much undefined behavior in the execution of
> | the most deterministic finite state automaton ever invented - the
> | modern computer?

> (1) they are not deterministic.

It depends on the definition of deterministic. The entire
machine responds in a deterministic manner to external stimuli.
The external stimuli (e.g. exactly when the clock pulse which
causes a change between threads) aren't in any way
deterministic, of course, and the C++ language has no way of
taking the entire machine into accout, so it is also at the
liberty of arbitrary actions in the OS (like not enough memory
being available to increase stack size).

> (2) "undefined behaviour" has a very specific meaning technical in the C++
> definition text. Look for it in the first clause.

And other languages use other terms. Off hand, I don't know of
any language which doesn't have some undefined behavior. The
only real difference is that some do not have the courage to
admit it. (And some were developed before much thought had been
given to the concept. The Fortran language specification may
not use the word, but it definitly describes program constructs
which are illegal, but do not require a diagnostic---and which
in real life act very much like what C and C++ call undefined

James Kanze (Gabi Software) email: james.kanze(a)
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 for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]