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

Feature request: Implement for loops with a for iterators #621

Open
64kramsystem opened this issue Aug 16, 2022 · 1 comment
Open

Feature request: Implement for loops with a for iterators #621

64kramsystem opened this issue Aug 16, 2022 · 1 comment

Comments

@64kramsystem
Copy link
Contributor

64kramsystem commented Aug 16, 2022

For loops are currently transpiled to while loops. I don't know if this is necessary in some cases, however, in the cases I've dealt with, the for loop could be converted directly, which makes the output considerably cleaner.

Example (simplified from the source):

for (loop = 0; loop < 16; loop++)
    if (digit == hexstr[loop]) {
      break;
    }
}

Transpiled to:

loop_0 = 0;
while loop_0 < 16 {
    if digit as i32 == hexstr[loop_0 as usize] as i32 {
        break;
    } else {
        loop_0 = loop_0.wrapping_add(1);
    }
}

Based on my understanding, C2Rust is trying to generalize a for loop where there can be a wraparound, however, there is a constant upper bound here, so there's no need for specific handling.

The simpler version is:

for loop_0 in 0..16 {
    if digit == hexstr[loop_0 as usize] {
        break;
    }
}
@kkysen
Copy link
Contributor

kkysen commented Aug 16, 2022

You're right that because the loop here has a constant bound, it can be simplified, but obviously that's not true in the general case. I'm not sure how difficult it is in the transpiler to detect such a thing, though. However, I do think the very common C pattern of

for (T i = start; i < end; i++) {
    ....
}

for integer types T where start and end are also of type T should be able to be converted to

for i in start..end {
    ...
}

because the upper bound (whether constant or not) ensures there will be no overflow. We'd just need to check that start and end are the same type, as otherwise casts and promotions could allow an overflow.

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

2 participants