www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Problem with integral promotions

reply Walter Bright <newshound2 digitalmars.com> writes:
They are supposed to match C. But they don't for unary operators + - ~, and as 
far as I can tell never did.

   https://issues.dlang.org/show_bug.cgi?id=16997
   https://issues.dlang.org/show_bug.cgi?id=17637

Note that the spec says:

"Note: unlike in C and C++, the usual integral promotions are not performed 
prior to the complement operation."

   http://dlang.org/spec/expression.html#complement_expressions

Where did that come from?

And the spec says nothing about unary - or unary +.

   http://dlang.org/spec/expression.html#unary-expression

It's been like this at least since D1, both the code and the Spec.

So, we have a choice:

1. Fix it so it matches C, as has been generally promised. Fixing it will break 
existing code such as:

   https://github.com/dlang/phobos/pull/5646

but worse, it may silently break code. I don't know of a reasonable way to 
detect this.

2. Codify existing practice, since it has been that way forever. Not matching C 
has caused problems, see 16997 and 17637. It may cause more serious silent 
problems for people converting C code to D code.
Jul 22
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
Walter Bright wrote:

 2. Codify existing practice, since it has been that way forever. Not 
 matching C has caused problems, see 16997 and 17637. It may cause more 
 serious silent problems for people converting C code to D code.
i'd say "codify, and add warning". since i patched the warning into the compiler, i have no more problems with the current rules: compiler tells me about possible incompatibilities with C, and i can either add `()` to silent the warning, or explicitly cast to the type i want. i think most other people will prefer to get warning instead of code breakage too. at least i hope so. ;-)
Jul 22
next sibling parent Guillaume Piolat <contact spam.com> writes:
On Saturday, 22 July 2017 at 10:51:05 UTC, ketmar wrote:
 Walter Bright wrote:

 2. Codify existing practice, since it has been that way 
 forever. Not matching C has caused problems, see 16997 and 
 17637. It may cause more serious silent problems for people 
 converting C code to D code.
i'd say "codify, and add warning".
I'd vote for the ketmar solution if workable. Another argument for this is that C code that has already been converted to D, and is currently silently broken, would benefit from a new warning as a way of gathering attention. However matching C promotion might make this code work too but silently.
Jul 22
prev sibling parent reply Jerry <hurricane hereiam.com> writes:
On Saturday, 22 July 2017 at 10:51:05 UTC, ketmar wrote:
 Walter Bright wrote:

 2. Codify existing practice, since it has been that way 
 forever. Not matching C has caused problems, see 16997 and 
 17637. It may cause more serious silent problems for people 
 converting C code to D code.
i'd say "codify, and add warning". since i patched the warning into the compiler, i have no more problems with the current rules: compiler tells me about possible incompatibilities with C, and i can either add `()` to silent the warning, or explicitly cast to the type i want. i think most other people will prefer to get warning instead of code breakage too. at least i hope so. ;-)
Good luck adding a warning into DMD. After years there still isn't a warning for unsigned/signed comparisons. What code would break? Are there any examples of D code that would break as a result of the change?
Jul 22
parent ketmar <ketmar ketmar.no-ip.org> writes:
Jerry wrote:

 What code would break? Are there any examples of D code that would break 
 as a result of the change?
basically, any template that has small integral type T and does unary +/-/~ on it. and there *is* such code in phobos, and it's not explicitly tested for different integral sizes. when i added a warning, i had to fix phobos in several places, but i'm pretty sure that there are ALOT more.
Jul 22
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
This affects:

~ubyte: all values
-ubyte: all values
-byte: -128 (0x80)

~ushort: all values
-ushort: all values
-short: -32768 (0x8000)
Jul 22
prev sibling next sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Saturday, 22 July 2017 at 10:44:04 UTC, Walter Bright wrote:
 Note that the spec says:

 "Note: unlike in C and C++, the usual integral promotions are 
 not performed prior to the complement operation."

   http://dlang.org/spec/expression.html#complement_expressions

 Where did that come from?
Git blames you: https://github.com/dlang/dlang.org/commit/4cd3f38bbabdde30b280738dab4f4184c06f05f9
Jul 22
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/22/2017 1:07 PM, Vladimir Panteleev wrote:
 Git blames you:
 
 https://github.com/dlang/dlang.org/commit/4cd3f38bbabdde30b280738dab4f4184c06f05f9
Ah, thanks for finding this. It was in response to: https://issues.dlang.org/show_bug.cgi?id=5132 i.e. it was documenting existing behavior.
Jul 22
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
OT: https://issues.dlang.org/show_bug.cgi?id=17417 can we also 
reconsider this?
Jul 24
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/24/2017 1:50 AM, Kagamin wrote:
 OT: https://issues.dlang.org/show_bug.cgi?id=17417 can we also reconsider this?
The bugzilla page was pretty clear about it.
Jul 24
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/22/17 6:44 AM, Walter Bright wrote:
 They are supposed to match C. But they don't for unary operators + - ~, 
 and as far as I can tell never did.
My opinion is that it should behave unsurprisingly. It's very surprising behavior for: ubyte x = 1; int y = -x; To make y = 255. My recommendation: 1. issue a warning for using any of those operators an unsigned type without an unambiguous cast. In other words: ubyte x = 1; -x; // warning cast(ubyte)-x; // OK, not changing size cast(int)-x; // warning -cast(int)x; // OK 2. Change the warning to a deprecation. 3. Change to an error optionally, you could finally implement the C behavior after this and remove the error, but I'm actually thinking that the number of times this comes up is probably so few that it's worth requiring the cast. Note, the negation of byte.min or short.min is not as surprising as the negation of unsigned types, as int or long have the same behavior, and it's a well-known corner case. Also note, you did not include char/wchar in your list of affected types, though they have the same behavior with those operators as ubyte and ushort. -Steve
Jul 24
parent reply Walter Bright <newshound2 digitalmars.com> writes:
Yes, I think a switch to enable the correct behavior, and a warning when the 
cases are encountered and the switch isn't thrown, is likely the best approach.
Jul 24
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/24/2017 2:07 PM, Walter Bright wrote:
 Yes, I think a switch to enable the correct behavior, and a warning when the 
 cases are encountered and the switch isn't thrown, is likely the best approach.
https://github.com/dlang/dmd/pull/7013
Jul 24
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/24/17 6:46 PM, Walter Bright wrote:
 On 7/24/2017 2:07 PM, Walter Bright wrote:
 Yes, I think a switch to enable the correct behavior, and a warning 
 when the cases are encountered and the switch isn't thrown, is likely 
 the best approach.
https://github.com/dlang/dmd/pull/7013
Yes, that should be workable. I'm looking at some of the code that you have to update, and I'm wondering if ~ should still operate the way it does. While - on an unsigned is somewhat clear that you want a negative (and therefore a different type), ~ on an unsigned actually makes sense for the same type. However, if C operates this way, this would be a huge trap for people who are porting code. -Steve
Jul 25
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/25/2017 6:43 AM, Steven Schveighoffer wrote:
 However, if C operates this way, this would be a huge trap for people who are 
 porting code.
That's right. Also for C/C++ programmers who are used to how C works.
Jul 25
prev sibling parent Random D user <no email.com> writes:
On Saturday, 22 July 2017 at 10:44:04 UTC, Walter Bright wrote:
 1. Fix it so it matches C, as has been generally promised. 
 Fixing it will break existing code such as:
If D was my language I'd fix it, since it's a bug. D's fluidity and effortlessness comes from a lot of small compounding convenience features. The converse is true as well. A lot of small annoyances accumulate into frustration.
Jul 24