www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Question about ubyte x overflow, any safe way?

reply matheus <matheus gmail.com> writes:
Hi,

The snippet below will produce an "infinite loop" because 
obviously "ubyte u" will overflow after 255:

import std.stdio;
void main(){
     ubyte u = 250;
     for(;u<256;++u){
         writeln(u);
     }
}

Question: Is there a way (Flag) to prevent this?

Matheus.
Aug 04 2019
next sibling parent reply Max Haughton <maxhaton gmail.com> writes:
On Sunday, 4 August 2019 at 18:12:48 UTC, matheus wrote:
 Hi,

 The snippet below will produce an "infinite loop" because 
 obviously "ubyte u" will overflow after 255:

 import std.stdio;
 void main(){
     ubyte u = 250;
     for(;u<256;++u){
         writeln(u);
     }
 }

 Question: Is there a way (Flag) to prevent this?

 Matheus.
What do you want to do? If you just want to count to 255 then use a foreach If you want to prevent overflow you must either use BigInt or wrap ubyte in a struct that doesn't allow overflow
Aug 04 2019
parent reply matheus <matheus gmail.com> writes:
On Sunday, 4 August 2019 at 18:15:30 UTC, Max Haughton wrote:
 What do you want to do? If you just want to count to 255 then 
 use a foreach
This was just an example, what I'd like in this code is either: Get an error (exception) when overflow or even an warning (Only if "some" flag was active).
 If you want to prevent overflow you must either use BigInt or 
 wrap ubyte in a struct that doesn't allow overflow
Could you please elaborate about this struct wrapping? Do you mean manually check on change? Matheus.
Aug 04 2019
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Sunday, 4 August 2019 at 18:22:30 UTC, matheus wrote:
 On Sunday, 4 August 2019 at 18:15:30 UTC, Max Haughton wrote:
 What do you want to do? If you just want to count to 255 then 
 use a foreach
This was just an example, what I'd like in this code is either: Get an error (exception) when overflow or even an warning (Only if "some" flag was active).
Use std.experimental.checkedint: import std.stdio; import std.experimental.checkedint; void main() { for(Checked!(ubyte, Throw) u = ubyte(250); u < 256; ++u) { writeln(u.get); } } An exception will be thrown when you attempt to increment u above 255.
Aug 04 2019
parent matheus <matheus gmail.com> writes:
On Sunday, 4 August 2019 at 18:38:34 UTC, Paul Backus wrote:
 ...
 Use std.experimental.checkedint:

 import std.stdio;
 import std.experimental.checkedint;

 void main()
 {
     for(Checked!(ubyte, Throw) u = ubyte(250); u < 256; ++u) {
         writeln(u.get);
     }
 }

 An exception will be thrown when you attempt to increment u 
 above 255.
Unfortunately I'm using DMD 2.072 which doesn't support this, but I'll upgrade soon as I can and will check this out. Thanks, Matheus.
Aug 04 2019
prev sibling parent Max Haughton <maxhaton gmail.com> writes:
On Sunday, 4 August 2019 at 18:22:30 UTC, matheus wrote:
 On Sunday, 4 August 2019 at 18:15:30 UTC, Max Haughton wrote:
 What do you want to do? If you just want to count to 255 then 
 use a foreach
This was just an example, what I'd like in this code is either: Get an error (exception) when overflow or even an warning (Only if "some" flag was active).
 If you want to prevent overflow you must either use BigInt or 
 wrap ubyte in a struct that doesn't allow overflow
Could you please elaborate about this struct wrapping? Do you mean manually check on change? Matheus.
Std.experimental.checkedint maybe exactly what you are looking for
Aug 04 2019
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 08/04/2019 11:12 AM, matheus wrote:
 Hi,
=20
 The snippet below will produce an "infinite loop" because obviously=20
 "ubyte u" will overflow after 255:
=20
 import std.stdio;
 void main(){
  =C2=A0=C2=A0=C2=A0 ubyte u =3D 250;
  =C2=A0=C2=A0=C2=A0 for(;u<256;++u){
  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 writeln(u);
  =C2=A0=C2=A0=C2=A0 }
 }
=20
 Question: Is there a way (Flag) to prevent this?
=20
 Matheus.
Two examples with foreach and ranges. The 'ubyte.max + 1' expression is=20 int. The compiler casts to ubyte (because we typed ubyte) in the foreach = and we cast to ubyte in the range: void main() { int count =3D 0; // (Explicit request for) implicit conversion to ubyte foreach (ubyte u; ubyte.min .. ubyte.max + 1) { ++count; } assert(count =3D=3D 256); import std.range; import std.algorithm; import std.conv; int count2 =3D 0; // Explicit conversion with to!ubyte iota(ubyte.max + 1).map!(to!ubyte).each!(_ =3D> ++count2); assert(count2 =3D=3D 256); } Ali
Aug 04 2019
parent reply matheus <matheus gmail.com> writes:
On Monday, 5 August 2019 at 01:41:06 UTC, Ali Çehreli wrote:
 ...
 Two examples with foreach and ranges. The 'ubyte.max + 1' 
 expression is int. The compiler casts to ubyte (because we 
 typed ubyte) in the foreach and we cast to ubyte in the range:
 ...
Maybe it was a bad example of my part (Using for), and indeed using foreach would solve that specific issue, but what I'm really looking for if there is a flag or a way to check for overflow when assigning some variable. ubyte u = 260; // Here should be given some warning or throw exception. It's ubyte, but it could be any other data type. Thanks anyway, Matheus.
Aug 05 2019
parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Monday, 5 August 2019 at 18:21:36 UTC, matheus wrote:
 On Monday, 5 August 2019 at 01:41:06 UTC, Ali Çehreli wrote:
 ...
 Two examples with foreach and ranges. The 'ubyte.max + 1' 
 expression is int. The compiler casts to ubyte (because we 
 typed ubyte) in the foreach and we cast to ubyte in the range:
 ...
Maybe it was a bad example of my part (Using for), and indeed using foreach would solve that specific issue, but what I'm really looking for if there is a flag or a way to check for overflow when assigning some variable. ubyte u = 260; // Here should be given some warning or throw exception. It's ubyte, but it could be any other data type.
Yes, no question. It's checkedint that you should use. It was written exactly for that purpose.
Aug 05 2019