Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integer overflow with new for loop #14700

Closed
IntegratedQuantum opened this issue Feb 21, 2023 · 3 comments
Closed

integer overflow with new for loop #14700

IntegratedQuantum opened this issue Feb 21, 2023 · 3 comments

Comments

@IntegratedQuantum
Copy link
Contributor

Zig Version

0.11.0-dev.1711+dc1f50e50

Steps to Reproduce and Observed Behavior

const std = @import("std");

pub fn main() void {
	var start: u32 = 1;
	var end: u32 = 0;
	for(start..end) |x| {
		std.log.info("{}", .{x});
	}
}

output:

$ zig run test.zig
thread 28234 panic: integer overflow
/home/mint/Desktop/test.zig:6:6: 0x20b56c in main (test)
 for(start..end) |x| {
     ^
/home/mint/Downloads/zig/lib/std/start.zig:607:22: 0x20aa25 in posixCallMainAndExit (test)
            root.main();
                     ^
/home/mint/Downloads/zig/lib/std/start.zig:376:5: 0x20a4d1 in _start (test)
    @call(.never_inline, posixCallMainAndExit, .{});
    ^
Aborted (core dumped)

Expected Behavior

I would expect these two loops to behave equivalent:

for(start..end) |x| {
	...
}
// should behave like
var x: usize = start
while(x < end) : (x += 1) {
	...
}

And therefor no integer overflow should happen.

workaround for anyone else who stumbles over this

for(start..@max(start, end)) |x| {
	...
}
@IntegratedQuantum IntegratedQuantum added the bug Observed behavior contradicts documented or intended behavior label Feb 21, 2023
@wooster0
Copy link
Contributor

wooster0 commented Feb 21, 2023

It sounds a bit like a proposal? At the moment I think this is behaving as expected.
It sounds like something I mentioned in #14671 (comment) and I was wondering if it would be worth opening a proposal for those different ranges, or if it is better to keep it as simple and limited as it is right now because maybe they would give more opportunities for logic errors to work unexpectedly.

@nektro
Copy link
Contributor

nektro commented Feb 21, 2023

I would definitely not expect the types to be padded out to usize, but i would expect this program to print 0 with no issue. this definitely seems like a bug indeed

edit: didnt realize it was going from 1 to 0

@andrewrk
Copy link
Member

andrewrk commented Feb 21, 2023

This is working as designed. You can't have a negative length. Note that if you make them const, you get a compile error:

test.zig:6:15: error: overflow of integer type 'u32' with value '-1'
    for (start..end) |x| {
         ~~~~~^~~~~

You also can't slice this way:

const std = @import("std");

pub fn main() void {
    const hello = "hello";
    const start: u32 = 1;
    const end: u32 = 0;
    const slice = hello[start..end];
    _ = slice;
}
test.zig:7:25: error: start index 1 is larger than end index 0
    const slice = hello[start..end];
                        ^~~~~

with runtime known values:

thread 2084384 panic: start index 1 is larger than end index 0
/home/andy/dev/zig/build-release/test.zig:7:24: 0x20b45a in main (test)
    const slice = hello[start..end];
                       ^

@andrewrk andrewrk closed this as not planned Won't fix, can't repro, duplicate, stale Feb 21, 2023
@andrewrk andrewrk removed the bug Observed behavior contradicts documented or intended behavior label Feb 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants