On Tue, 6 Jul 2021 at 16:39, Xi Ruoyao <xry111@xxxxxxxxxxxxxxxx> wrote: > > On Sat, 2021-07-03 at 16:36 +0100, Jonny Grant wrote: > > > > > > On 16/06/2021 14:36, Xi Ruoyao wrote: > > > On Wed, 2021-06-16 at 14:01 +0100, Jonny Grant wrote: > > > > > > > Chris Latner also mentioned integer overflow being undefined, that > > > > crops up too. There's no easy solution right, we need to hand write > > > > code the checks? It's human-error prone if we need to manually code > > > > each check. throwing in C++, or handling in C. > > > > > > > > if(N >= INT_MAX) > > > > { > > > > throw std::overflow_error("N >= INT_MAX would overflow in for > > > > loop"); > > > > } > > > > > > > > for (i = 0; i <= N; ++i) > > > > { > > > > // ... > > > > } > > > > > > For debugging use -fsanitize=undefined. > > > > > > And this is buggy anyway, no matter if there is an UB: > > > > > > for (unsigned i = 0; i <= N; i++) > > > make_some_side_effect_without_any_undefined_behavior(i); > > > > > > If N may be UINT_MAX, this is not UB, but a dead loop. Programming is > > > just human-error prone, even if you use "some programming language > > > claimed to be able to eliminate many human errors" (I'll not say its > > > name, to prevent a flame war). > > > > > Hi Xi > > > > > > Checking the UINT_MAX would at least prevent the continual running of > > any such buggy loop where it increments right? and the code within the > > loop does not modify 'i' > > > > for (unsigned i = 0; (i <= N) && (i != UINT_MAX); i++) > > make_some_side_effect_without_any_undefined_behavior(i); > > Even if i is signed, it will still "work" if you modify the && > expression a little: > > for (int i = 0; i != UINT_MAX && i < N; i++) > make_some_side_effect_without_any_undefined_behavior(i); > > The problem is, now the behavior when N == UINT_MAX is same with when N > == (UINT_MAX - 1). This can really puzzle someone who will call your > function. > > If I'm designing this function I'd make it to interpret N as [0, N), > instead of [0, N]: > > // Do something for each integer in [0, N). > void do_something(int N) > { > for (int i = 0; i < N; i++) > do_something_once(i); > } That's good, specify the limit. > > > Is there any way to have a way to make loop variables like this 'i' > > const within the body of the loop, to avoid accidental changing of 'i' > > by the body of the loop > > I don't think there is one in C. Perhaps, maybe use some "nasty" > macros. Probably I could use this pattern to avoid the risk of code modifying the loop counter by accident. for (int loop_var = 0; loop_var < N; loop_var++) { const int i = loop_var; printf("i: %d\n", i); } Jonny