Thread: Wouldn't this be against convention or something?

  1. #1
    Registered User
    Join Date
    Sep 2017
    Posts
    93

    Wouldn't this be against convention or something?

    I've been looking at some code to print out the current directory the executable is located.

    Here's GNU's code for a simple directory listing program:

    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    
    int
    main (void)
    {
      DIR *dp;
      struct dirent *ep;
    
    
      dp = opendir ("./");
      if (dp != NULL)
        {
          while (ep = readdir (dp))
            puts (ep->d_name);
          (void) closedir (dp);
        }
      else
        perror ("Couldn't open the directory");
    
    
      return 0;
    }
    Yeah, it works, but the first thing I noticed sticking out like a sore thumb was "while(ep = readdir(dp))".

    When I tried compiling it the first time, my suspicions were proven correct from Clang.

    Here's the Clang warning:

    $ clang -o dirlisting dirlisting.c
    dirlisting.c:13:18: warning: using the result of an assignment as a condition
    without parentheses [-Wparentheses]
    while(ep = readdir(dp))
    ~~~^~~~~~~~~~~~~
    dirlisting.c:13:18: note: place parentheses around the assignment to silence
    this warning
    while(ep = readdir(dp))
    ^
    ( )
    dirlisting.c:13:18: note: use '==' to turn this assignment into an equality
    comparison
    while(ep = readdir(dp))
    ^
    ==
    1 warning generated.
    Here's what I came up with...and it does the same thing and it's shorter code:

    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    
    int main() {
        DIR *dp;
        
        struct dirent *ep;
        
        dp = opendir("./");
    
        if(dp == NULL)
            perror("Could not open directory.\n");
        
        while(dp != NULL) {
            ep = readdir(dp);
            puts(ep->d_name);
        }
        
        closedir(dp);
            
        return 0;
    }
    Last edited by ImageJPEG; 12-02-2017 at 08:44 PM.

  2. #2
    Registered User
    Join Date
    Sep 2017
    Posts
    93
    Oh, and this is from GNU's own site

    The GNU C Library: Simple Directory Lister

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    The issue with GNU code style choices is... complicated. Take a look here:
    GNU Coding Standards
    I, for one, disagree with almost everything that section says, but I'm not the one making GNU programs so what do I know...
    Devoted my life to programming...

  4. #4
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by ImageJPEG View Post
    Here's what I came up with...and it does the same thing and it's shorter code:

    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    
    int main() {
        DIR *dp;
        
        struct dirent *ep;
        
        dp = opendir("./");
    
        if(dp == NULL)
            perror("Could not open directory.\n");
        
        while(dp != NULL) {
            ep = readdir(dp);
            puts(ep->d_name);
        }
        
        closedir(dp);
            
        return 0;
    }
    Your code doesn't do the same thing. The while loop in your code doesn't stop when ep becomes NULL (well, it probably does stop, with a segfault, when you try to dereference a null pointer).

  5. #5
    Registered User
    Join Date
    Sep 2017
    Posts
    93
    Wouldn't dp have to become null to give ep a null value? If that's the case, wouldn't the while loop terminate itself since it depends on dp != NULL?

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    No. There's nothing inside that loop that even changes dp. And ep becomes null when when there are no more directory entries to read (or if there's an error reading the directory).

  7. #7
    Registered User
    Join Date
    Sep 2017
    Posts
    93
    Oh, I was thinking it worked similar to getc where it grabs the next character each time the loop is iterated.

    So it's just a matter if adding:

    Code:
    if(ep == NULL)
        break;
    Right?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    while ((ep = readdir (dp))!=NULL)
    The emphasised bits are implied by the language. Where NULL may be replaced by 0, '\0' or 0.0 depending on the actual type of the assignment.

    It can be a sign of a mistake, especially as it's far too easy to write = when you meant ==. So modern compilers now hint that writing out the assignment with an explicit comparison is the way to go.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Sure, that would work. But I would do it the way it's done in the original code as it's an idiomatic way to read "something" from "somewhere" for as long as there are more "somethings" to read.

    Read one character at a time from stdin until there are no more characters to read:
    Code:
    int c;
    while ((c = getchar()) != EOF) {
        // do something with the character
    }
    Read one line at a time from stdin until there are no more lines to read:
    Code:
    char buf[1000];
    while (fgets(stdin, buf, sizeof buf)) {
        // do something with the line
    }
    Read one directory entry at a time from dp until there are no more directory entries to read:
    Code:
    struct dirent *ep;
    while ((ep = readdir(dp))) {
        // do something with the directory entry
    }
    Note that you can just put parentheses around the expression "ep = readdir(dp)" to tell the compiler that you meant to use "=" as an assignment and not as a comparison (it's just a compiler warning because it's usually a mistake to use "=" instead of "==" in a while or if statement).

  10. #10
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by christop View Post
    Sure, that would work. But I would do it the way it's done in the original code as it's an idiomatic way to read "something" from "somewhere" for as long as there are more "somethings" to read.
    Your examples are nothing like the original code (you use parenthesis)

  11. #11
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by Hodor View Post
    Your examples are nothing like the original code (you use parenthesis)
    My last example (with readdir) is exactly like the original GNU version except for the parentheses. The parentheses do nothing but prevent the compiler from warning about using "=" instead of "==". They don't change what the code does.

  12. #12
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by christop View Post
    My last example (with readdir) is exactly like the original GNU version except for the parentheses. The parentheses do nothing but prevent the compiler from warning about using "=" instead of "==". They don't change what the code does.
    Correct. And the OP was asking if omitting the parenthesis was "against convention"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Wouldn't this be about the same as a class in C++?
    By HelpfulPerson in forum C Programming
    Replies: 27
    Last Post: 08-10-2013, 06:38 AM
  2. I've a problem. Obviously, else I wouldn't be here.
    By Yinyang107 in forum C Programming
    Replies: 6
    Last Post: 12-11-2010, 09:56 AM
  3. please help i'm so new to this you wouldn't believe
    By jaquenta in forum C Programming
    Replies: 7
    Last Post: 12-09-2008, 08:49 AM
  4. Replies: 2
    Last Post: 01-04-2003, 01:16 AM
  5. wouldn't it be funny if...
    By doubleanti in forum A Brief History of Cprogramming.com
    Replies: 27
    Last Post: 02-05-2002, 06:11 PM

Tags for this Thread