Thread: Loop and Side-Effect

  1. #1
    Banned
    Join Date
    Jul 2022
    Posts
    112

    Loop and Side-Effect

    Can this be considered as a side-effect, bad practice ?

    Code:
    char empty[1] = {0};
    
    while (array[i]) {
    
        // more code
    
        if (abc()) {
            array = empty;
            i = -1;
    
        }
        i = 1 + i;
    }

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Yes!

    Why would you do this?

    Better:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
      while(1)   // Infinite loop
      {
        if(Some false condition)
        {
          break;
        }
      }
      return 0;
    }

  3. #3
    Banned
    Join Date
    Jul 2022
    Posts
    112
    I would rather avoid break;

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Quote Originally Posted by kodax View Post
    I would rather avoid break;
    while(1), break, continue, are all the normal way to handle loops, and infinite loops, in C programming. If you use other methods, then you are on your own.

  5. #5
    Banned
    Join Date
    Jul 2022
    Posts
    112
    Infinite loop is also bad.

    If statement is the correct way to do it, although the overhead will increase.

  6. #6
    Banned
    Join Date
    Jul 2022
    Posts
    112
    while(1), break, continue, are all the normal way to handle loops, and infinite loops, in C programming
    Infinite loops may be normal in C, but in purely functional languages,
    they would be considered terrible.

    This is good, with the overhead though.

    Code:
    while (1 == boolean) {
    
        if (abc()) {
            boolean = 0;
     
        } else if (array[i]) { // More code
    
        }
        i = 1 + i;
    }
    Last edited by kodax; 11-02-2022 at 10:50 AM.

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by kodax View Post
    Infinite loops may be normal in C, but in purely functional languages,
    they would be considered terrible.

    This is good, with the overhead though.

    Code:
    while (1 == boolean) {
    
        if (abc()) {
            boolean = 0;
     
        } else if (array[i]) { // More code
    
        }
        i = 1 + i;
    }
    Whatever programming language you're trying to transfer a concept from, I suggest for your own sanity you stop, infinite loops are NEVER a bad thing, they're just another tool in the shed to achieve things with, what IS a bad thing is using them incorrectly because then you're forced to kill the loop externally. An example of where an infinite loop would be good is waiting on signals from other threads/processes, there you rarely want them to time out an instead want them to only end on the death of the waiter, waitee or when the appropriate signal is given, all of which are checked for inside the loop rather than at it's header as it's both inconvenient & ugly to do it in the header, possibly confusing also to some readers

  8. #8
    Banned
    Join Date
    Jul 2022
    Posts
    112
    I suggest for your own sanity you stop
    Projection.

  9. #9
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    It really depends exactly what you're trying to do. Based on your last code I might write it thus:

    Code:
    for (int i = 0; !abc(); ++i) {
        if (array[i]) { // More code
        }
    }
    One thing this does that yours doesn't is declare and initialize i. That part can be modified or taken out as needed.

  10. #10
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    What am I missing? Why do you need empty at all? Just use NULL

    Code:
    void my_function(int array[]) {
       int i = 0;
       while (array && array[i]) {
           // more code   
           if (abc()) {
               array = NULL;
           }
           i = 1 + i;
       }
    }

  11. #11
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    No, on second through I'm agreeing with the others - it is a folly to not use 'break' in this case.


    However if you do want to avoid using break that original code isn't the way to go about it. I've put three versions into Compiler Explorer:

    Code:
    #include <stdlib.h>
    
    
    int abc(void);
    
    
    void my_function1(char array[]) {
       int i = 0;
       while (array && array[i]) {
           // more code   
           if (abc()) {
               array = NULL;
           }
           i = 1 + i;
       }
    }
    
    
     
    void my_function2(char array[]) {
       char empty[1] = {0};
       int i = 0;
       while (array[i]) {
          // more code 
          if (abc()) {
             array = empty;
             i = -1;   
          }
          i = 1 + i;
       }
    }



    This is the resulting code:


    Code:
    my_function1(char*):
            test    rdi, rdi
            je      .L9
            push    rbx
            mov     rbx, rdi
    .L3:
            cmp     BYTE PTR [rbx], 0
            je      .L1
            call    abc()
            add     rbx, 1
            test    eax, eax
            je      .L3
    .L1:
            pop     rbx
            ret
    .L9:
            ret
    
    
    my_function2(char*):
            cmp     BYTE PTR [rdi], 0
            je      .L20
            push    rbp
            mov     rbp, rdi
            push    rbx
            xor     ebx, ebx
            sub     rsp, 8
    .L14:
            call    abc()
            test    eax, eax
            je      .L23
            add     rsp, 8
            pop     rbx
            pop     rbp
            ret
    .L23:
            add     ebx, 1
            movsx   rax, ebx
            cmp     BYTE PTR [rbp+0+rax], 0
            jne     .L14
            add     rsp, 8
            pop     rbx
            pop     rbp
            ret
    .L20:
            ret
    The top one looks to produce nicer code to me...

  12. #12
    Banned
    Join Date
    Jul 2022
    Posts
    112
    What am I missing
    1. If block sets array to empty, to break out of the loop.
    2. If block does error handling, this will be useful after the loop.

    Code:
    while (array && array[i])
    3. While block will never be executed..

  13. #13
    Banned
    Join Date
    Jul 2022
    Posts
    112
    While ( 1 == boolean ) does the job, it's good.
    Last edited by kodax; 11-02-2022 at 03:28 PM.

  14. #14
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Again, it all depends on exactly what you're trying to do. What is array? I can only deduce that it's a pointer (not an array), since you can't assign to an array. Are you returning that pointer to a caller, or what else do you need to do with it after the loop ends? Also, what does "empty" mean? The empty array is not actually empty--it contains a single element (it is, however, a valid zero-length string, but initializing it with array syntax suggests you're not treating it as a string).

    We can all post code that does what we think you're trying to do, based only on the code that you've posted so far, but it's still not clear what you want the code to do.

  15. #15
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Quote Originally Posted by kodax View Post
    1. If block sets array to empty, to break out of the loop.
    2. If block does error handling, this will be useful after the loop.

    Code:
    while (array && array[i])
    3. While block will never be executed..
    Can you expand in points 2 and 3, because I can't see what you are getting at.... here's the two implementations, with abc() changed to see if the string has a 'z' in it, and doing 'error handling'. Both implementation produce the same output (except one doesn't segfault if it is passed a NULL).

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    
    int abc(char c) {
       return c == 'z';
    }
    
    
    void my_function1(char array[]) {
       int i = 0;
       while (array && array[i]) {
           // more code
           putchar(array[i]);
    
           if (abc(array[i])) {
               array = NULL;
           }
           i = 1 + i;
       }
       if(!array) {
          printf("It had a 'z' in it \n");
       }
    }
    
    
    void my_function2(char array[]) {
       char empty[1] = {0};
       int i = 0;
       while (array[i]) {
          // more code
          putchar(array[i]);
    
          if (abc(array[i])) {
             array = empty;
             i = -1;
          }
          i = 1 + i;
       }
       if(array == empty) {
          printf("It had a 'z' in it \n");
       }
    }
    
    
    int main(void) {
       my_function1("Hello!\n");
       my_function2("Hello!\n");
       return 0;
    }
    Code:
    $ ./a
    Hello!
    Hello!
    (using 'break' is better than either of them... IMO)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 09-14-2017, 11:44 AM
  2. Replies: 7
    Last Post: 10-14-2016, 12:02 PM
  3. Replies: 26
    Last Post: 03-08-2011, 05:23 PM
  4. Replies: 2
    Last Post: 11-13-2009, 05:33 AM
  5. Side effect of various operations
    By xds4lx in forum C++ Programming
    Replies: 3
    Last Post: 03-11-2002, 10:12 AM

Tags for this Thread