Consider the following C++ program: ----- #include <cstdio> int main() { signed char c = -128; printf("%d\n", (int)(-c)); return 0; } ----- This prints "128". Consider the supposedly identical D code: ----- import core.stdc.stdio; void main() { byte c = -128; printf("%d\n", cast(int)(-c)); // -128 } ----- Since the D unary minus doesn't promote byte to int, it yields a different result. This is a real case that costed ketmar 40 min, while porting working C code. Porting to D silently broke the code due to subtly different integer promotion rules. I'm pretty sure I would have given up becasue code that is translated is often enough not understood yet. After investigation: * Taking the unary minus of byte and short and then asting to int yield different results for the lowest values: -128 and -32768 * Taking the unary minus of ubyte and ushort and then casting to int yield different results for any value except 0 Why are the promotion rules for unary + and - different from C?
Created attachment 1626 [details] Patch in ketmar DMD fork ("aliced") to make unary +/- on small integers a warning
Created attachment 1627 [details] warning on unary minus/plus fixed patch, made against vanilla. it will show warning for unary -/+ for (u)byte and (u)short, but one can silence that with `-(expr)`. it prolly needs better message with explanation of what it is, and what to do, and why -- but i leave that for that one who will make a PR out of the patch.
as for the question: promotion rules are what they are currently to allow this: byte n; n = -n; if unary minus will promote `n`, you will need to add `cast` there. and negate never ever drop bits from integer (even byte.min is essentially unchanged, so no info is lost), so it is -- relatively -- safe to not promote here.
p.s.: i'm not that smart, tbh, i understood the rationale behind the design after alot of hard thinking.
https://github.com/dlang/dmd/pull/7013
*** Issue 17637 has been marked as a duplicate of this issue. ***
Unary + and unary ~ are also broken in the same way.
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 And the spec says nothing about unary - or unary +. http://dlang.org/spec/expression.html#unary-expression
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/47d9a09e66d7fde929b596a72450a92d51d0b3e1 bigint: fix dependency on broken Issue 16997 https://github.com/dlang/phobos/commit/c1832981e3818a151ee25805d47d472633a218ad Merge pull request #5646 from WalterBright/bigint-cast bigint: fix dependency on broken Issue 16997 merged-on-behalf-of: Andrei Alexandrescu <andralex@users.noreply.github.com>
Commits pushed to stable at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/47d9a09e66d7fde929b596a72450a92d51d0b3e1 bigint: fix dependency on broken Issue 16997 https://github.com/dlang/phobos/commit/c1832981e3818a151ee25805d47d472633a218ad Merge pull request #5646 from WalterBright/bigint-cast
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/71403b6cd3781cd4d97104be1f4194e168a75d02 fix Issue 16997 - Integral promotion rules not being followed for unary + - ~ expressions https://github.com/dlang/dmd/commit/7253190083cd66ae11711f2f6ff15497810d34c5 Merge pull request #7013 from WalterBright/fix16997 fix Issue 16997 - Integral promotion rules not being followed for neg...
Commits pushed to stable at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/71403b6cd3781cd4d97104be1f4194e168a75d02 fix Issue 16997 - Integral promotion rules not being followed for unary + - ~ expressions https://github.com/dlang/dmd/commit/7253190083cd66ae11711f2f6ff15497810d34c5 Merge pull request #7013 from WalterBright/fix16997
Commits pushed to dmd-cxx at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/47d9a09e66d7fde929b596a72450a92d51d0b3e1 bigint: fix dependency on broken Issue 16997 https://github.com/dlang/phobos/commit/c1832981e3818a151ee25805d47d472633a218ad Merge pull request #5646 from WalterBright/bigint-cast
Great! D is now a bit easier to explain.
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル