Bug 13387 – Bug with arithmetic opertions on integer types smaller than int
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-08-28T06:25:06Z
Last change time
2020-03-21T03:56:41Z
Assigned to
No Owner
Creator
Uranuz
Comments
Comment #0 by neuranuz — 2014-08-28T06:25:06Z
I consider it is buggy behaviour that when I sum two values of the same type and I get resulting value of another type. And also when sum two integer values of different type I think that resulting value must be biggest in size type of these two, but not other third type that is not expected to be.
//----------
void main()
{
ubyte a = 1;
ushort b = 2;
ushort c = a + b;
}
// Error: cannot implicitly convert expression (cast(int)a + cast(int)b) of type int to ushort
//----------
void main()
{
byte a = 1;
byte b = 2;
byte c = a + b;
}
//----------
void main()
{
short a = 1;
short b = 2;
short c = a - b;
}
//----------
Also I consider assigning uint to int without explicit cast is senseless and unsafe
//----------
void main()
{
uint a = uint.max;
int c = a; //This must issue an error
}
//----------
But this could be allowed because ubyte max number could be stored in int or in short
//----------
void main()
{
ubyte a = ubyte.max;
short b = a; //Is OK
int c = a; //Is OK
}
//----------
Also implicit cast from byte, short. etc. with combination with *alias this* becomes source of silent bugs. But I don't know what to do with it, because forbidding all the integer implicit casts is not good to, because assigning short -> int is useful in most cases.
Example that demonstrates these silent bugs with using alias this and integers:
//----------
import std.stdio, std.typecons;
interface ListControl
{
@property {
void selValue(int value);
void selValue(Nullable!int value);
}
}
class CheckBoxList: ListControl
{
override @property {
void selValue(int value)
{
writeln("value: int");
}
void selValue(Nullable!int value)
{
writeln("value: Nullable!int");
}
}
}
void main()
{
//Someone considered to make it of byte type
//instead of int to save memory
Nullable!byte myValue; //it is null/uninitialized
//Creating object
auto checkBoxList = new CheckBoxList;
//Let's assign value to our property
//You see that types don't match. But let's imagine that it is a complicated project
//and class implementation and *myValue* located in different modules so programmer don't remember right type
checkBoxList.selValue = myValue; //This just silently fails in runtime without some compile-time error
}
//----------
More simple example shows that Nullable based on integer types is source of silent (at compile-time) bugs
//----------
import std.typecons;
void main()
{
Nullable!byte a;
Nullable!int b;
b = a; //This fails in runtime
}
//----------
Comment #1 by neuranuz — 2014-08-28T07:06:39Z
AFAIK, in C++ the same rules used, but it don't have problems with assignment of type *unsigned short = unsigned short + unsigned short*. So it's strange that we have such type of problem in D. But still integer promotions are used to, although I disagree with it.
//-------------
#include <iostream>
#include <typeinfo>
int main()
{
unsigned short a = 5;
unsigned short b = 3;
unsigned short c = a + b; //This compiles
if( typeid(a + b) == typeid(int) )
{
std::cout << "int" << std::endl;
}
else if( typeid(a + b) == typeid(unsigned short) )
{
std::cout << "unsigned short" << std::endl;
}
else if( typeid(a + b) == typeid(unsigned int) )
{
std::cout << "unsigned int" << std::endl;
}
return 0;
}
//-------------
This programme outputs:
int
Comment #2 by bearophile_hugs — 2014-08-29T06:59:14Z
(In reply to Uranuz from comment #1)
> So it's strange that we have such type of problem in D.
It's a "problem" introduced on purposes in D.
Regarding byte+byte=int it's done like this in D to follow the C rules. I think it's hard to change this.
Comment #3 by b2.temp — 2020-02-20T11:04:12Z
There's nothing applicable here, despite of personnal preferences. Implicit conversions and integral promotions rules are specified and this cannot change without creating massive breakages.