format for declaring variables?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Daniel Rudy

    #16
    Style (Was: Re: format for declaring variables?)

    At about the time of 2/9/2007 2:20 AM, Chris Dollin stated the following:
    Daniel Rudy wrote:
    >
    >OT: Speaking of style, forms like this bug me:
    >>
    >if ((fc = open(filename)) < 0)
    > errx("file error %d\n", errno);
    >>
    >How hard is it to sit there and do this instead?
    >>
    >fc = open(filename);
    >if (fc < 0) errx("file error %d\n", errno);
    >>
    >It's just so much easier to read, less error prone (since there are
    >fewer nested () ), and it probably generates the exact same code at the
    >machine level.
    >
    But doesn't work as part of an else-if without putting up
    extra scaffolding.
    >
    (Myself, I want to know why I can't put /declarations/ in
    the conditions of an if [1,2].)
    >
    [1] Because then I don't have to introduce variables before
    I know their values.
    >
    [2] Yes, it can be done cleanly, although I haven't thought
    hard about it /for C/.
    >
    I've seen code like this that compiles just fine under C with all
    warnings enabled (or at least the ones that I have turned on):

    int function(int i)
    {
    switch(i)
    {
    case 0:
    {
    int a;
    /* do something */
    return(0);
    }
    case 1:
    {
    char *p;
    /* do something */
    return(0);
    }
    case 2:
    {
    unsigned long lax;
    /* do something */
    return(0);
    }
    default:
    return(1);
    }
    return(0);
    }

    And here's the actual code:

    char * inet_ntop_host( const struct sockaddr *sa, socklen_t salen)
    {
    char portstr[8];
    static char str[128];

    switch(sa->sa_family)
    {
    case AF_INET:
    {
    struct sockaddr_in *sin = (struct sockaddr_in *) sa;
    if (inet_ntop(AF_I NET, &sin->sin_addr, str, sizeof(str)) ==
    NULL) return(NULL);
    if(ntohs(sin->sin_port) != 0)
    {
    snprintf(portst r, sizeof(portstr) , ":%d",
    ntohs(sin->sin_port));
    strcat(str, portstr);
    }
    return(str);
    }
    #ifdef IPV6
    case AF_INET6:
    {
    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
    if (inet_ntop(AF_I NET6, &sin6->sin6_addr, str, sizeof(str))
    == NULL) return(NULL);
    if(ntohs(sin6->sin6_port) != 0)
    {
    snprintf(portst r, sizeof(portstr) , ":%d",
    ntohs(sini6->sin6_port));
    strcat(str, portstr);
    }
    return(str);
    }
    #endif
    #ifdef AF_UNIX
    case AF_UNIX:
    {
    struct sockaddr_un *unp = (struct sockaddr_un *) sa;
    if (unp->sun_path[0] == 0) strcpy(str, "(no pathname bound)");
    else snprintf(str, sizeof(str), "%s", unp->sun_path);
    return(str);
    }
    #endif
    default:
    snprintf(str, sizeof(str), "sock_ntop_host : unknown AF_xxx:
    %d, len %d", sa->sa_family, salen);
    return(NULL);
    break;
    }
    return(NULL);
    }

    --
    Daniel Rudy

    Email address has been base64 encoded to reduce spam
    Decode email address using b64decode or uudecode -m

    Why geeks like computers: look chat date touch grep make unzip
    strip view finger mount fcsk more fcsk yes spray umount sleep

    Comment

    • Daniel Rudy

      #17
      Re: format for declaring variables?

      At about the time of 2/9/2007 2:32 AM, Richard Heathfield stated the
      following:
      Daniel Rudy said:
      >
      >At about the time of 2/9/2007 2:03 AM, Richard Heathfield stated the
      >following:
      >>Daniel Rudy said:
      >>>
      >><snip>
      >>>
      >>>Anyways, I know that this IS platform specific,
      >>Fortunately , that doesn't matter here (and anyway, you tried,
      >>right?).
      >>>
      >Tried? Not sure what you mean there...
      >
      I mean that you made an effort in your original article to present the
      problem in a platform-independent way - which was good. Okay, it didn't
      work out on this occasion, and it turns out it didn't matter anyway,
      but you did make the effort.
      >
      Oh, ok.

      So I get a B for effort then? I guess I would have gotten an A if my
      example was correct.

      --
      Daniel Rudy

      Email address has been base64 encoded to reduce spam
      Decode email address using b64decode or uudecode -m

      Why geeks like computers: look chat date touch grep make unzip
      strip view finger mount fcsk more fcsk yes spray umount sleep

      Comment

      • Daniel Rudy

        #18
        Re: format for declaring variables?

        At about the time of 2/9/2007 7:22 AM, CBFalconer stated the following:
        Daniel Rudy wrote:
        ... snip ...
        >OT: Speaking of style, forms like this bug me:
        >>
        >if ((fc = open(filename)) < 0)
        > errx("file error %d\n", errno);
        >>
        >How hard is it to sit there and do this instead?
        >>
        >fc = open(filename);
        >if (fc < 0) errx("file error %d\n", errno);
        >>
        >It's just so much easier to read, less error prone (since there
        >are fewer nested () ), and it probably generates the exact same
        >code at the machine level.
        >
        While I am annoyed by (not to mention the non-existent open):
        Hmm...open(2) exists on my system, but then again, I'm running Unix, so
        it's probably not in the standard C library. It does the same thing as
        fopen though, but take different parameters.
        >
        fc = fopen(filename, etc);
        if (!fc) erroraction();
        dowhatever(fc);
        >
        when
        >
        if (!(fc = fopen(filename, etc)))
        erroraction(fil ename);
        else (
        /* all is well */
        dowhatever(fc);
        }
        I would write that like this:

        fc = fopen(filename, etc);
        if (fc == NULL)
        {
        ERR("fopen failed", errno, 1)
        return(EFUNCTER R);
        }
        dowhatever(fc);
        return(0);

        ERR is a macro that I made that is defined like this:

        #define ERR(MM,CC,EE) ERROR(MM, PARAM_XXX_ERROR _SHOW,
        PARAM_XXX_ERROR _FATAL, CC, EE)

        From there, there is a #define ERROR and then it goes on to my error
        handler.

        will show me precisely what is required to get to dowhatever, or to
        erroraction. I also know that I will not fall into dowhatever when
        erroraction (somewhere else) returns. I also trivially know that
        dowhatever has a valid opened fc value passed to it.
        >
        Note that the preferred method above can be wrapped in:
        >
        do {
        filename = getfcspecificat ion();
        if (!(fc = fopen(filename, etc)))
        erroraction(fil ename);
        else (
        /* all is well */
        dowhatever(fc);
        }
        } while (!fc);
        fclose(fc); /* knowing that fc is non-NULL */
        >
        It is clearer because the thing that is being tested is the success
        of fopen, not the value of fc (which is incidental). It also leads
        to single entry / single exit modules, and conserves vertical
        space, all of which enhances code readability.
        >
        Think it over.
        >
        The problem that I have with that is the if line.

        if (!(fc = fopen(filename, etc)))

        I'm not savvy doing tricks like that, so I would have to think about
        that statement to fully grasp the meaning of it. For the most part, I
        follow the single entry / exit, but in the case of errors, I do an
        immediate return with an error indication.

        --
        Daniel Rudy

        Email address has been base64 encoded to reduce spam
        Decode email address using b64decode or uudecode -m

        Why geeks like computers: look chat date touch grep make unzip
        strip view finger mount fcsk more fcsk yes spray umount sleep

        Comment

        • Keith Thompson

          #19
          Re: format for declaring variables?

          Daniel Rudy <spamthis@spamt his.netwrites:
          At about the time of 2/9/2007 3:09 AM, Keith Thompson stated the following:
          [...]
          >There are two permitted forms for main:
          >>
          > int main(int argc, char *argv[]) { /* ... */ }
          >>
          > int main(void) { /* ... */ }
          >>
          >(or equivalent).
          >>
          >This:
          >>
          > int main(argc, argv)
          > int argc;
          > char *argv;
          > {
          > /* ... */
          > }
          >>
          >is an old-style declaration; it's still legal, but it shouldn't be
          >used in new code.
          >>
          >
          Which begs the question as to why they did it that way.
          I think it goes back to C's ancestor languages B and BCPL, and
          possibly to Fortran. In the old days, the idea was that the compiler
          would generate code for a call to a function based on the arguments in
          the call; they weren't cross-checked against what the function
          expected. The declarations of the types of the parameters are
          internal to the function, and not visible at the point of call. If
          you correctly pass an int and a char**, that's great. If you pass a
          double and a function pointer, you lose, and the compiler won't help
          you by printing an error message.

          Prototypes, which specify the number and types of the expected
          arguments, were a considerable improvement.

          [...]
          I've never used anything but this for programs that take command line
          arguments:
          >
          int main(int argc, char **argv)
          >
          But you say that you can also do this?
          >
          int main(int argc, char *argv[])
          In a parameter declaration (and *only* in a parameter declaration),
          "char **argv" and "char *argv[]" are exactly equivalent.

          The relationship between arrays and pointers in C is a tremendous
          source of confusion. It's not really all that complex once you learn
          the rules. But this special-case rule that what looks like an array
          parameter declaration is really a pointer parameter declaration just
          adds to the confusion, in my opinion. I recommend sections 4 and 6 of
          the comp.lang.c FAQ, <http://www.c-faq.com/>.

          --
          Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
          San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
          We must do something. This is something. Therefore, we must do this.

          Comment

          • Christopher Layne

            #20
            Re: Style (Was: Re: format for declaring variables?)

            Daniel Rudy wrote:
            >Daniel Rudy wrote:
            >>
            >>OT: Speaking of style, forms like this bug me:
            >>>
            >>if ((fc = open(filename)) < 0)
            >> errx("file error %d\n", errno);
            >>>
            >>How hard is it to sit there and do this instead?
            Hard. Get used to the idiom, it's not a big deal unless it's causing line
            wrapping issues. The idiom will become familiar to you in use.
            >>fc = open(filename);
            >>if (fc < 0) errx("file error %d\n", errno);
            >>>
            >>It's just so much easier to read, less error prone (since there are
            >>fewer nested () ), and it probably generates the exact same code at the
            >>machine level.
            Vertical real estate is always in demand unless you've got a different type of
            monitor/terminal.
            I've seen code like this that compiles just fine under C with all
            warnings enabled (or at least the ones that I have turned on):
            But you forgot the -Wimpending-beating option for indentation like that. That
            is ridiculous.

            Regardless of your level of affinity towards Linux (which might well be none
            since I saw you mention FBSD), this is a good guide with clean semantics and
            pragmatic execution:

            Linux Kernel Coding Style guide:


            With such classic Linus gems such as:

            16 Chapter 1: Indentation
            17
            18 Tabs are 8 characters, and thus indentations are also 8 characters.
            19 There are heretic movements that try to make indentations 4 (or even 2!)
            20 characters deep, and that is akin to trying to define the value of PI to
            21 be 3.
            22
            23 Rationale: The whole idea behind indentation is to clearly define where
            24 a block of control starts and ends. Especially when you've been looking
            25 at your screen for 20 straight hours, you'll find it a lot easier to see
            26 how the indentation works if you have large indentations.
            27
            28 Now, some people will claim that having 8-character indentations makes
            29 the code move too far to the right, and makes it hard to read on a
            30 80-character terminal screen. The answer to that is that if you need
            31 more than 3 levels of indentation, you're screwed anyway, and should fix
            32 your program.

            and

            97 Chapter 3: Placing Braces and Spaces
            98
            99 The other issue that always comes up in C styling is the placement of
            100 braces. Unlike the indent size, there are few technical reasons to
            101 choose one placement strategy over the other, but the preferred way, as
            102 shown to us by the prophets Kernighan and Ritchie, is to put the opening
            103 brace last on the line, and put the closing brace first, thusly:
            104
            105 if (x is true) {
            106 we do y
            107 }
            [...]
            108
            123 However, there is one special case, namely functions: they have the
            124 opening brace at the beginning of the next line, thus:
            125
            126 int function(int x)
            127 {
            128 body of function
            129 }
            130
            131 Heretic people all over the world have claimed that this inconsistency
            132 is ... well ... inconsistent, but all right-thinking people know that
            133 (a) K&R are _right_ and (b) K&R are right. Besides, functions are
            134 special anyway (you can't nest them in C).

            Amen.

            Comment

            • pete

              #21
              Re: Style (Was: Re: format for declaring variables?)

              Christopher Layne wrote:
              Besides, functions are
              134 special anyway (you can't nest them in C).
              Function definitions are special in C.
              Besides being the only exclusively external declarations,
              they are also the only declarations
              that are not terminated by a semicolon.

              --
              pete

              Comment

              • CBFalconer

                #22
                Re: Style (Was: Re: format for declaring variables?)

                Christopher Layne wrote:
                >
                .... snip ...
                108
                123 However, there is one special case, namely functions: they
                124 have the opening brace at the beginning of the next line, thus:
                125
                126 int function(int x)
                127 {
                128 body of function
                129 }
                Not an anomaly, rather an outgrowth of the original K&R declaration
                format:

                int function(foo, bar)
                int foo;
                double bar;
                {
                body
                }

                and as such now often ignored by:

                int function(int foo, double bar) {
                body
                }

                --
                <http://www.cs.auckland .ac.nz/~pgut001/pubs/vista_cost.txt>
                <http://www.securityfoc us.com/columnists/423>

                "A man who is right every time is not likely to do very much."
                -- Francis Crick, co-discover of DNA
                "There is nothing more amazing than stupidity in action."
                -- Thomas Matthews


                Comment

                • Barry Schwarz

                  #23
                  Re: Style (Was: Re: format for declaring variables?)

                  On Wed, 14 Feb 2007 13:42:17 GMT, pete <pfiland@mindsp ring.comwrote:
                  >Christopher Layne wrote:
                  >
                  >Linux Kernel Coding Style guide:
                  >http://www.mjmwired.net/kernel/Docum...on/CodingStyle
                  >
                  > Besides, functions are
                  >134 special anyway (you can't nest them in C).
                  >
                  >Function definitions are special in C.
                  >Besides being the only exclusively external declarations,
                  The static keyword can remove the external attribute.
                  >they are also the only declarations
                  >that are not terminated by a semicolon.

                  Remove del for email

                  Comment

                  • pete

                    #24
                    Re: Style (Was: Re: format for declaring variables?)

                    Barry Schwarz wrote:
                    >
                    On Wed, 14 Feb 2007 13:42:17 GMT, pete <pfiland@mindsp ring.comwrote:
                    >
                    Christopher Layne wrote:
                    Besides, functions are
                    134 special anyway (you can't nest them in C).
                    Function definitions are special in C.
                    Besides being the only exclusively external declarations,
                    >
                    The static keyword can remove the external attribute.
                    I don't think that you know what "external declarations" are.

                    N869
                    6.9 External definitions

                    Semantics

                    [#4] As discussed in 5.1.1.1, the unit of program text after
                    preprocessing is a translation unit, which consists of a
                    sequence of external declarations. These are described as
                    ``external'' because they appear outside any function (and
                    hence have file scope).
                    they are also the only declarations
                    that are not terminated by a semicolon.
                    --
                    pete

                    Comment

                    • Barry Schwarz

                      #25
                      Re: Style (Was: Re: format for declaring variables?)

                      On Thu, 15 Feb 2007 04:01:40 GMT, pete <pfiland@mindsp ring.comwrote:
                      >Barry Schwarz wrote:
                      >>
                      >On Wed, 14 Feb 2007 13:42:17 GMT, pete <pfiland@mindsp ring.comwrote:
                      >>
                      >Christopher Layne wrote:
                      >
                      >Linux Kernel Coding Style guide:
                      >http://www.mjmwired.net/kernel/Docum...on/CodingStyle
                      >
                      > Besides, functions are
                      >134 special anyway (you can't nest them in C).
                      >
                      >Function definitions are special in C.
                      >Besides being the only exclusively external declarations,
                      >>
                      >The static keyword can remove the external attribute.
                      >
                      >I don't think that you know what "external declarations" are.
                      You're probably right but the only reason I commented was because I
                      was thinking of external linkage which is unrelated to the topic under
                      discussion. My apologies.


                      Remove del for email

                      Comment

                      Working...