February 28, 2005
<brad@domain.invalid> wrote in message news:cvvrs8$e8v$1@digitaldaemon.com...
> Just a comment from the sidelines - feel free to ignore.
> To me it doesn't look like Walter is in any hurry to flag narrowing
> casts as warnings (or add any warnings into D at all).  And it doesn't
> look like everyone else is willing to give up without a fight.  Why not
> use this as an opportunity to get started on a D lint program?  There
> are enough skilled people with a stake in this particular issue alone to
> make it worth while.
> Walter - how hard, in your opinion, is it to add lint like checking into
> the GPL D frontend?

Not hard. Of course, that depends on how far one wants to go with it.

> Can it be some in a painless way so that future
> updates to the frontend have low impact on the lint code?

Painless, probably not. But I try to be careful not to introduce wholesale or gratuitous changes, because I don't want to upset GDC. If the lint additions are marked in the source, it probably wouldn't be too hairy to fold them into future versions. It probably also would only be necessary to occaisionally do this, not with every update to DMD.


February 28, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cvvs75$ehg$1@digitaldaemon.com...
> Ok, I'm sold on integral promotion.
>
> Then the answer is that we must have narrowing warnings. I can't see a sensible alternative. Sorry

You might be interested in that:

int foo(char c)
{
    int i = 300;
    foo(i);
    c = c + 1;
    return c;
}

compiled with:

    gcc -c -Wall test.c

produces no warnings. Neither does:

    g++ -c -Wall test.c


February 28, 2005
On Mon, 28 Feb 2005 10:06:58 -0800, Walter wrote:

> "Derek" <derek@psych.ward> wrote in message news:1uxqa6iv5mgq3.hjei032qxzwk.dlg@40tude.net...
>> On Mon, 28 Feb 2005 02:01:18 -0800, Walter wrote:
>>
>>> "Walter" <newshound@digitalmars.com> wrote in message
>>>     b = cast(typeof(b))(b + 1);
>>
>> Unless the '1' was interpreted to be a byte rather than an int. DMD gives up trying to soon. A '1' is a member of many integer subsets, not just the 'int' subset.
> 
> Even if the '1' was typed as a byte, such as with a cast, you'd still have to write:
> 
>     b = cast(typeof(b))(b + cast(typeof(b))1);
> 
> because of the integral promotion rules: given (e1 + e2), both are promoted to ints or uints if they are integral types smaller than ints or uints. The integral promotion rules are taken from C, and I believe it would be a huge mistake to try and rewrite them.

I'm also looking forward to the day when somebody designs the language which learns from *all* the mistakes of C, C++ and D.

-- 
Derek
Melbourne, Australia
February 28, 2005
In article <cvvp0e$b66$1@digitaldaemon.com>, Walter says...
>
>
>"Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:cvv05a$2gnu$1@digitaldaemon.com...
>> Sorry, but that's only required if all integral expressions must be
>promoted to (at least) int.
>
>Right.
>
>> Who says that's the one true path?
>
>Breaking that would make transliterating C and C++ code into D an essentially impractical task. It's even worse than trying to "fix" C's operator precedence levels.
>
>> Why is int the level at which it's drawn?
>
>Because of the long history of the C notion of 'int' being the natural size of the underlying CPU, and the incestuous tendency of CPU's to be designed to execute C code efficiently. (Just to show what kind of trouble one can get into with things like this, the early Java spec required floating point behavior to be different than how the most popular floating point hardware on the planet wanted to do it. This caused Java implementations to be either slow or non-compliant.) CPUs makers, listening to their marketing department, optimize their designs for C, and that means the default integral promotion rules. Note that doing short arithmetic on Intel CPUs is slow and clunky.


This appears to be thoroughly misleading. We're talking about what the compiler enforces as the model of correctness; /not/ how that is translated into machine code. Do you see the distinction, Walter?


>Note that when the initial C standard was being drawn up, there was an unfortunate reality that there were two main branches of default integral promotions - the "sign preserving" and "value preserving" camps. They were different in some edge cases. One way had to be picked, the newly wrong compilers had to be fixed, and some old code would break. There was a lot of wailing and gnashing and a minor earthquake about it, but everyone realized it had to be done. That was a *minor* change compared to throwing out default integral promotions.


Great stuff for the talk show, but unrelated. D is not C ~ you've already broken that concept in so many ways.


>> Why can there not a bit more contextual information applied? Is there no smarter way of dealing with it?
>
>Start pulling on that string, and everything starts coming apart, especially for overloading and partial specialization.


On the face of it, the contrary would be true. However, that hardly answers Matthew's question about whether there's another approach. Instead it seems to indicate that you don't know of one, or are not open to one. Or am I misreading this?


>CPUs are designed to execute C semantics
>efficiently. That pretty much nails down accepting C's operator precedence
>and default integral promotion rules as is.


Misleading and invalid. Your argument fully binds the language model to the machine-code model. There's no need for them to be as tightly bound as you claim. Sure, there's tension between the two ~ but you are claiming it's all or nothing. It may have been a number of years since I wrote a compiler, but I don't buy this nonsense. And neither should anyone else.


- Kris



February 28, 2005
'cause if it's not part of the language spec, it might as well not exist.

Several commentators (including IIRC, the original authors of the language; must trip off and check my copy of The Art Of UNIX Programming ...) have observed that the biggest single mistake in the development of the C language was having, for reasons of program size, the lint functionality as a separate program. Most people don't use it.

Consider the case of C++, which is simply too complicated for an effective lint.

And anyway, there's the more fundamental thing that if any item's going to be effectively mandatory in lint, it should be in the compiler in the first place. As I've said before, which competent C++ engineer does not set warnings to max?

<brad@domain.invalid> wrote in message news:cvvrs8$e8v$1@digitaldaemon.com...
> Just a comment from the sidelines - feel free to ignore.
> To me it doesn't look like Walter is in any hurry to flag narrowing
> casts as warnings (or add any warnings into D at all).  And it doesn't
> look like everyone else is willing to give up without a fight.  Why
> not use this as an opportunity to get started on a D lint program?
> There are enough skilled people with a stake in this particular issue
> alone to make it worth while.
> Walter - how hard, in your opinion, is it to add lint like checking
> into the GPL D frontend?  Can it be some in a painless way so that
> future updates to the frontend have low impact on the lint code?
>
> Brad


February 28, 2005
"Walter" <newshound@digitalmars.com> wrote in message news:cvvtnq$gjk$2@digitaldaemon.com...
>
> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cvvs75$ehg$1@digitaldaemon.com...
>> Ok, I'm sold on integral promotion.
>>
>> Then the answer is that we must have narrowing warnings. I can't see
>> a
>> sensible alternative. Sorry
>
> You might be interested in that:
>
> int foo(char c)
> {
>    int i = 300;
>    foo(i);
>    c = c + 1;
>    return c;
> }
>
> compiled with:
>
>    gcc -c -Wall test.c
>
> produces no warnings. Neither does:
>
>    g++ -c -Wall test.c

Why? Does that prove you right? Me?

All it says is that G++ is not perfect, which I already knew.

How come sometimes all that's needed to justify something in D is to show something wrong in C++? Not much of an evolution. More like a statis in different colour.

:-(



February 28, 2005
In article <cvvqp9$d89$1@digitaldaemon.com>, Walter says...
>
>There's a lot there, and I just want to respond to a couple of points.
>
>1) You ask what's the bug risk with having a lot of casts. The point of a cast is to *escape* the typing rules of the language. Consider the extreme case where the compiler inserted a cast whereever there was any type mismatch. Typechecking pretty much will just go out the window.
>
>2) You said you use C++ every time when you want speed. That implies you feel that C++ is inherently more efficient than D (or anything else). That isn't my experience with D compared with C++. D is faster. DMDScript in D is faster than the C++ version. The string program in D www.digitalmars.com/d/cppstrings.html is much faster in D. The dhrystone benchmark is faster in D.
>
>And this is using an optimizer and back end that is designed to efficiently optimize C/C++ code, not D code. What can be done with a D optimizer hasn't even been explored yet.
>
>There's a lot of conventional wisdom that since C++ offers low level control, that therefore C++ code executes more efficiently. The emperor has no clothes, Matthew! I can offer detailed explanations of why this is true if you like.
>
>I challenge you to take the C++ program in www.digitalmars.com/d/cppstrings.html and make it faster than the D version. Use any C++ technique, hack, trick, you need to.


There is no doubt in my mind that array slicing is a huge factor in making D faster than C in very specific areas. I'm a big proponent of this.

Having said that; making sweeping statements regarding "low level control" and so on does nobody any favours. I would very much like to hear this detailed explanation you offer:



February 28, 2005
Matthew wrote:
> 'cause if it's not part of the language spec, it might as well not exist.
> 
> Several commentators (including IIRC, the original authors of the language; must trip off and check my copy of The Art Of UNIX Programming ...) have observed that the biggest single mistake in the development of the C language was having, for reasons of program size, the lint functionality as a separate program. Most people don't use it.
> 
> Consider the case of C++, which is simply too complicated for an effective lint.
> 
> And anyway, there's the more fundamental thing that if any item's going to be effectively mandatory in lint, it should be in the compiler in the first place. As I've said before, which competent C++ engineer does not set warnings to max?
> 

I agree.  However, I think that with a lint like program built into the existing frontend via a #define would provide good quantitative evidence on this issue, and others.
At the moment the whole thread boils down to "I like it one way" vs "I like it the other way".
With a lint program built into the frontend, I think that you will have harder evidence either way.  For example, add narrowing warnings to the frontend, run it over Mango.  If it turns up genuine bugs, then the "warn on narrowing cast" crowd is proved right.  If it turns up no actual bugs, well Walter's case is stronger.
At the moment it is just a face off between two (obviously qualified experts) who happen to have differing opinions.

Brad
February 28, 2005
Walter wrote:
> "Matthew" <admin.hat@stlsoft.dot.org> wrote in message
> news:cvv05b$2gnu$2@digitaldaemon.com...
> 
>>But the example itself is bogus. Let's look at it again, with a bit more
> 
> flesh:
> 
>>    byte b;
>>
>>    b = 255
>>
>>    b = b + 1;
>>
>>Hmmm .... do we still want that implicit behaviour? I think not!!
> 
> 
> Yes, we do want it. Consider the following:
> 
>     byte b;
>     int a,c;
>     ...
>     a = b + 1 + c;
> 
> Do you really want the subexpression (b + 1) to "wrap around" on byte
> overflow? No. The notion of the default integral promotions is *deeply*
> rooted in the C psyche. Breaking this would mean that quite a lot of
> complicated, debugged, working C expressions will subtly break if
> transliterated into D. People routinely use the shorter integral types to
> save memory, and the expressions using them *expect* them to be promoted to
> int. D will just get thrown out the window by any programmer having to
> write:
> 
>     a = cast(int)b + 1 + c;
> 
> The default integral promotion rules are what makes the plethora of integral
> types in C (and D) usable.

Wouldn't it be possible to produce an error only in the case that the result of an expression is stored (or otherwise used) in a type smaller than any other type that was involved in the expression, with constants handled as being the smallest type they can be that preserves their value? (what an ugly sentence :) I think I understand the need for default integral promotions and I don't think this would hurt that.. In other words, the expressions still get evaluated like they do now, the only thing that changes is that the maximum size of all operators in an expression is checked, and if the assignee (left part of =, or function parameter type) is smaller, it is an error, otherwise it is not..

For example:

byte=int+int; // error, must use cast
int=byte+short; // OK, the same as it works now (both get cast to int
                // before being added up)
int=3+short; // OK, both 3 and short are used as int (like now)
short=short+5; // OK - 5 fits into short
short=short+50000; // error, because 50000 is int
int=byte+1+int; // OK, this is the above example
int=100+100; // OK, you get 200, because expansion-to-int is still done
             // even though 100s could be considered as bytes
short=int+short; // error - int is larger than short in the result
short=30000+30000; // error - constant expression is evaluated as ints
                   // and it doesn't fit in short, even though
                   // both 30000s do


xs0
February 28, 2005
> short=short+5; // OK - 5 fits into short

Not necessarily

> int=byte+1+int; // OK, this is the above example

Not necessarily