Conditional operator using void expression

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dan Henry

    Conditional operator using void expression

    I have run across functions in the Linux kernel's MTD driver that have
    me scratching my head a bit. The functions have the general form:

    extern int bar(size_t len, size_t *retlen, unsigned char *buf);

    int foo(size_t len, unsigned char *buf) {
    size_t retlen;
    int ret;

    ret = bar(len, &retlen, buf);
    return ret ? : retlen; /* <-- void expression and UB? */
    }

    It is foo()'s return statement that I am soliciting comments about. Am
    I correct that the conditional operator's second operand is a void
    expression and if so, doesn't that invoke undefined behavior by
    attempting to use the value of a void expression? I sometimes
    struggle interpreting the standard and hope I haven't overlooked
    something, but I can't find the verse that might bless the statement.
    If it is allowed, what value would foo() return for nonzero ret --
    zero?

    Thanks,

    --
    Dan Henry
  • Ian Collins

    #2
    Re: Conditional operator using void expression

    Dan Henry wrote:
    I have run across functions in the Linux kernel's MTD driver that have
    me scratching my head a bit. The functions have the general form:
    >
    extern int bar(size_t len, size_t *retlen, unsigned char *buf);
    >
    int foo(size_t len, unsigned char *buf) {
    size_t retlen;
    int ret;
    >
    ret = bar(len, &retlen, buf);
    return ret ? : retlen; /* <-- void expression and UB? */
    }
    >
    It is foo()'s return statement that I am soliciting comments about. Am
    I correct that the conditional operator's second operand is a void
    expression and if so, doesn't that invoke undefined behavior by
    attempting to use the value of a void expression? I sometimes
    struggle interpreting the standard and hope I haven't overlooked
    something, but I can't find the verse that might bless the statement.
    If it is allowed, what value would foo() return for nonzero ret --
    zero?
    >
    I think it's a syntax error, but gcc accepts it without complaint in
    default mode. It does warn in strict mode:

    gcc -Wall -pedantic -ansi x.c
    x.c: In function `foo':
    x.c:11: warning: ISO C forbids omitting the middle term of a ?: expression

    I guess Linux kernel hackers don't use strict mode :)

    --
    Ian Collins.

    Comment

    • Keith Thompson

      #3
      Re: Conditional operator using void expression

      Dan Henry <usenet@danlhen ry.comwrites:
      I have run across functions in the Linux kernel's MTD driver that have
      me scratching my head a bit. The functions have the general form:
      >
      extern int bar(size_t len, size_t *retlen, unsigned char *buf);
      >
      int foo(size_t len, unsigned char *buf) {
      size_t retlen;
      int ret;
      >
      ret = bar(len, &retlen, buf);
      return ret ? : retlen; /* <-- void expression and UB? */
      }
      >
      It is foo()'s return statement that I am soliciting comments about. Am
      I correct that the conditional operator's second operand is a void
      expression and if so, doesn't that invoke undefined behavior by
      attempting to use the value of a void expression?
      [...]

      No, it's not a void expression. A void expression would be an
      expression of type void, such as (void)42. What appears between the
      '?' and ':' is an empty token sequence, and is not an expression at
      all. As far as standard C is concerned, it's simply a syntax error.

      As an extension, gcc allows the middle operand of the conditional
      operator to be omitted; see the gcc documentation for details. This
      is a permissible extension, since it doesn't affect the behavior of
      any strictly conforming program.

      gcc with the "-pedantic" option correctly issues a warning for this.

      --
      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."
      -- Antony Jay and Jonathan Lynn, "Yes Minister"

      Comment

      • Robert Gamble

        #4
        Re: Conditional operator using void expression

        On Feb 26, 7:34 pm, Dan Henry <use...@danlhen ry.comwrote:
        I have run across functions in the Linux kernel's MTD driver that have
        me scratching my head a bit. The functions have the general form:
        >
        extern int bar(size_t len, size_t *retlen, unsigned char *buf);
        >
        int foo(size_t len, unsigned char *buf) {
        size_t retlen;
        int ret;
        >
        ret = bar(len, &retlen, buf);
        return ret ? : retlen; /* <-- void expression and UB? */
        >
        }
        >
        It is foo()'s return statement that I am soliciting comments about. Am
        I correct that the conditional operator's second operand is a void
        expression and if so, doesn't that invoke undefined behavior by
        attempting to use the value of a void expression?
        It's not a void expression, it's the lack of an expression. It isn't
        valid Standard C but is a gcc extension in which:
        x ? : y;
        is treated as:
        x ? x : y;

        It's a useful extension but it isn't Standard.

        Robert Gamble


        Comment

        • santosh

          #5
          Re: Conditional operator using void expression


          Dan Henry wrote:
          I have run across functions in the Linux kernel's MTD driver that have
          me scratching my head a bit. The functions have the general form:
          >
          extern int bar(size_t len, size_t *retlen, unsigned char *buf);
          >
          int foo(size_t len, unsigned char *buf) {
          size_t retlen;
          int ret;
          >
          ret = bar(len, &retlen, buf);
          return ret ? : retlen; /* <-- void expression and UB? */
          }
          >
          It is foo()'s return statement that I am soliciting comments about. Am
          I correct that the conditional operator's second operand is a void
          expression and if so, doesn't that invoke undefined behavior by
          attempting to use the value of a void expression? I sometimes
          struggle interpreting the standard and hope I haven't overlooked
          something, but I can't find the verse that might bless the statement.
          If it is allowed, what value would foo() return for nonzero ret --
          zero?
          >
          Thanks,
          In general the Linux kernel makes unapolegetic use of gcc's
          extensions, of which this is one. It a form of shortcut that evaluates
          to:

          return ret ? ret : retlen;

          Comment

          • CBFalconer

            #6
            Re: Conditional operator using void expression

            Robert Gamble wrote:
            On Feb 26, 7:34 pm, Dan Henry <use...@danlhen ry.comwrote:
            >
            .... snip ...
            > return ret ? : retlen; /* <-- void expression and UB? */
            >>
            >It is foo()'s return statement that I am soliciting comments
            >about. Am I correct that the conditional operator's second
            >operand is a void expression and if so, doesn't that invoke
            >undefined behavior by attempting to use the value of a void
            >expression?
            >
            It's not a void expression, it's the lack of an expression. It
            isn't valid Standard C but is a gcc extension in which:
            x ? : y;
            is treated as:
            x ? x : y;
            >
            It's a useful extension but it isn't Standard.
            As far as I am concerned, using it is extremely sloppy programming
            when portable programming would only require one extra identifier.
            It's all very well to use extensions when they actually help, but
            stupid when they are unnecessary.

            --
            Chuck F (cbfalconer at maineline dot net)
            Available for consulting/temporary embedded and systems.
            <http://cbfalconer.home .att.net>


            Comment

            • Dan Henry

              #7
              Re: Conditional operator using void expression

              On Mon, 26 Feb 2007 16:53:22 -0800, Keith Thompson <kst-u@mib.org>
              wrote:
              >Dan Henry <usenet@danlhen ry.comwrites:
              >I have run across functions in the Linux kernel's MTD driver that have
              >me scratching my head a bit. The functions have the general form:
              >>
              >extern int bar(size_t len, size_t *retlen, unsigned char *buf);
              >>
              >int foo(size_t len, unsigned char *buf) {
              > size_t retlen;
              > int ret;
              >>
              > ret = bar(len, &retlen, buf);
              > return ret ? : retlen; /* <-- void expression and UB? */
              >}
              >>
              >It is foo()'s return statement that I am soliciting comments about. Am
              >I correct that the conditional operator's second operand is a void
              >expression and if so, doesn't that invoke undefined behavior by
              >attempting to use the value of a void expression?
              >[...]
              >
              >No, it's not a void expression. A void expression would be an
              >expression of type void, such as (void)42. What appears between the
              >'?' and ':' is an empty token sequence, and is not an expression at
              >all. As far as standard C is concerned, it's simply a syntax error.
              >
              >As an extension, gcc allows the middle operand of the conditional
              >operator to be omitted; see the gcc documentation for details. This
              >is a permissible extension, since it doesn't affect the behavior of
              >any strictly conforming program.
              >
              >gcc with the "-pedantic" option correctly issues a warning for this.
              Ian, Keith, Robert, and santosh:

              Thank you all for your gentle guidance. I am not often fooled by
              GCC-isms, but that *gratuitous* extension caught me thinking that I
              had missed some corner-case of language usage.

              I have emphasized *gratuitous* above because, in my opinion, that
              extension (if limited to that bit of functionality, and I'll be
              looking it up tomorrow to see if it is that limited) offers very
              little or perhaps even negative benefit if one factors in the cost of
              having to think about it even being an extension -- but that's just
              me.

              [Ranting OT rhetorical question]
              I can appreciate some GCC-isms in the context of "the kernel" easing
              some things, but really now, is eliminating/shorthanding the second
              operand *that* useful?
              [/Ranting OT rhetorical question]

              --
              Dan Henry

              Comment

              • Mike King

                #8
                Re: Conditional operator using void expression

                Man, you guys are brutal! "obdurate" is the word of the day that comes to
                mind... How often does a "legit" post come along?

                "CBFalconer " <cbfalconer@yah oo.comwrote in message
                news:45E3B50B.2 45940E4@yahoo.c om...
                Robert Gamble wrote:
                >On Feb 26, 7:34 pm, Dan Henry <use...@danlhen ry.comwrote:
                >>
                ... snip ...
                >> return ret ? : retlen; /* <-- void expression and UB? */
                >>>
                >>It is foo()'s return statement that I am soliciting comments
                >>about. Am I correct that the conditional operator's second
                >>operand is a void expression and if so, doesn't that invoke
                >>undefined behavior by attempting to use the value of a void
                >>expression?
                >>
                >It's not a void expression, it's the lack of an expression. It
                >isn't valid Standard C but is a gcc extension in which:
                >x ? : y;
                >is treated as:
                >x ? x : y;
                >>
                >It's a useful extension but it isn't Standard.
                >
                As far as I am concerned, using it is extremely sloppy programming
                when portable programming would only require one extra identifier.
                It's all very well to use extensions when they actually help, but
                stupid when they are unnecessary.
                >
                --
                Chuck F (cbfalconer at maineline dot net)
                Available for consulting/temporary embedded and systems.
                <http://cbfalconer.home .att.net>
                >
                >

                Comment

                • santosh

                  #9
                  Re: Conditional operator using void expression

                  Mike King wrote:

                  [top-post fixed]
                  "CBFalconer " <cbfalconer@yah oo.comwrote in message
                  news:45E3B50B.2 45940E4@yahoo.c om...
                  Robert Gamble wrote:
                  On Feb 26, 7:34 pm, Dan Henry <use...@danlhen ry.comwrote:
                  >
                  ... snip ...
                  > return ret ? : retlen; /* <-- void expression and UB? */
                  >>
                  >It is foo()'s return statement that I am soliciting comments
                  >about. Am I correct that the conditional operator's second
                  >operand is a void expression and if so, doesn't that invoke
                  >undefined behavior by attempting to use the value of a void
                  >expression?
                  >
                  It's not a void expression, it's the lack of an expression. It
                  isn't valid Standard C but is a gcc extension in which:
                  x ? : y;
                  is treated as:
                  x ? x : y;
                  >
                  It's a useful extension but it isn't Standard.
                  As far as I am concerned, using it is extremely sloppy programming
                  when portable programming would only require one extra identifier.
                  It's all very well to use extensions when they actually help, but
                  stupid when they are unnecessary.
                  Man, you guys are brutal! "obdurate" is the word of the day that comes to
                  mind... How often does a "legit" post come along?
                  As far as I can see, nobody is criticising the OP for his genuine
                  mistake. Also I should probably warn you that you'll shortly be
                  advised not to top-post.

                  Comment

                  • Keith Thompson

                    #10
                    Re: Conditional operator using void expression

                    Dan Henry <usenet@danlhen ry.comwrites:
                    [...]
                    Thank you all for your gentle guidance. I am not often fooled by
                    GCC-isms, but that *gratuitous* extension caught me thinking that I
                    had missed some corner-case of language usage.
                    >
                    I have emphasized *gratuitous* above because, in my opinion, that
                    extension (if limited to that bit of functionality, and I'll be
                    looking it up tomorrow to see if it is that limited) offers very
                    little or perhaps even negative benefit if one factors in the cost of
                    having to think about it even being an extension -- but that's just
                    me.
                    >
                    [Ranting OT rhetorical question]
                    I can appreciate some GCC-isms in the context of "the kernel" easing
                    some things, but really now, is eliminating/shorthanding the second
                    operand *that* useful?
                    [/Ranting OT rhetorical question]
                    Quoting the gcc documentation:

                    In this simple case, the ability to omit the middle operand is not
                    especially useful. When it becomes useful is when the first
                    operand does, or may (if it is a macro argument), contain a side
                    effect. Then repeating the operand in the middle would perform
                    the side effect twice. Omitting the middle operand uses the value
                    already computed without the undesirable effects of recomputing
                    it.

                    I'm not necessarily arguing that the Linux kernel *should* use this
                    particular extension, but since the decision has already been made to
                    use gcc-specific features (to the extent that compiling the kernel
                    with anything other than gcc is nearly impossible), I suppose it's
                    just a matter of the kernel being written in GNU-C rather than C.

                    (I think Intel's icc can also compile the kernel, but a lot of effort
                    has been put into making it gcc-compatible.)

                    --
                    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."
                    -- Antony Jay and Jonathan Lynn, "Yes Minister"

                    Comment

                    • jaysome

                      #11
                      Re: Conditional operator using void expression

                      On Mon, 26 Feb 2007 23:26:15 -0600, "Mike King" <wmk77@cox.netw rote:
                      >Man, you guys are brutal! "obdurate" is the word of the day that comes to
                      >mind... How often does a "legit" post come along?
                      Admonishing sloppy programming, which is arguably what the OP's
                      example constituted, should not be labeled "obdurate". Just as
                      admonishing top-posting should not be labeled "obdurate" (awkward
                      context as a result of your top-posting follows).
                      >"CBFalconer " <cbfalconer@yah oo.comwrote in message
                      [snip]
                      >As far as I am concerned, using it is extremely sloppy programming
                      >when portable programming would only require one extra identifier.
                      >It's all very well to use extensions when they actually help, but
                      >stupid when they are unnecessary.
                      >>
                      >--
                      >Chuck F (cbfalconer at maineline dot net)
                      > Available for consulting/temporary embedded and systems.
                      > <http://cbfalconer.home .att.net>

                      Comment

                      • Flash Gordon

                        #12
                        Re: Conditional operator using void expression

                        santosh wrote, On 27/02/07 06:27:
                        Mike King wrote:
                        >
                        [top-post fixed]
                        >
                        >"CBFalconer " <cbfalconer@yah oo.comwrote in message
                        >news:45E3B50B. 245940E4@yahoo. com...
                        >>Robert Gamble wrote:
                        >>>On Feb 26, 7:34 pm, Dan Henry <use...@danlhen ry.comwrote:
                        <snip discussion of what turnout out to be a gcc extension>
                        >>>It's a useful extension but it isn't Standard.
                        >>As far as I am concerned, using it is extremely sloppy programming
                        >>when portable programming would only require one extra identifier.
                        >>It's all very well to use extensions when they actually help, but
                        >>stupid when they are unnecessary.
                        >>>
                        >Man, you guys are brutal! "obdurate" is the word of the day that comes to
                        >mind... How often does a "legit" post come along?
                        The OPs posts have been "legit". The OP asked about something he thought
                        must be standard C, and this is the right place for that, and has
                        accepted the the expert advice that it is not standard C. The OP even
                        went on to express an opinion about the use of such extensions that I
                        believe many of the regulars here (including me) would agree with.
                        As far as I can see, nobody is criticising the OP for his genuine
                        mistake.
                        I would say that the OPs mistake in assuming it was standard C was
                        entirely understandable so I think it unlikely that the OP will be
                        criticised by those it is worth reading here.
                        Also I should probably warn you that you'll shortly be
                        advised not to top-post.
                        OK, we can't have you being mistaken about such a thing.

                        Mike, please don't top post, your reply belongs after (or interspersed
                        with the text you are replying to. See most of the posts in this group
                        for examples including the one you were replying to.
                        --
                        Flash Gordon

                        Comment

                        • Richard Tobin

                          #13
                          Re: Conditional operator using void expression

                          In article <lnodng2ho0.fsf @nuthaus.mib.or g>,
                          Keith Thompson <kst-u@mib.orgwrote:
                          >Quoting the gcc documentation:
                          >
                          In this simple case, the ability to omit the middle operand is not
                          especially useful. When it becomes useful is when the first
                          operand does, or may (if it is a macro argument), contain a side
                          effect. Then repeating the operand in the middle would perform
                          the side effect twice. Omitting the middle operand uses the value
                          already computed without the undesirable effects of recomputing
                          it.
                          I don't find this very convincing. The usual reason for macros of this
                          kind is efficiency, and the usual reason for using them rather than
                          inline functions is portability to systems that don't provide them.
                          Since GCC does support inline functions, using a different GCC-specific
                          mechanism is pointless.

                          -- Richard
                          --
                          "Considerat ion shall be given to the need for as many as 32 characters
                          in some alphabets" - X3.4, 1963.

                          Comment

                          • Yevgen Muntyan

                            #14
                            Re: Conditional operator using void expression

                            Mike King wrote:
                            Man, you guys are brutal! "obdurate" is the word of the day that comes to
                            mind...
                            It happens, nevermind.
                            How often does a "legit" post come along?
                            Not very often. Usually when it is "how do I return
                            a char array from function" or similar. And you
                            better don't top-post here, it's dangerous, can invoke
                            undefined behavior of some regulars.

                            [snip essay about sloppiness and happiness]

                            Best regards,
                            Yevgen

                            Comment

                            • Yevgen Muntyan

                              #15
                              Re: Conditional operator using void expression

                              Richard Tobin wrote:
                              In article <lnodng2ho0.fsf @nuthaus.mib.or g>,
                              Keith Thompson <kst-u@mib.orgwrote:
                              >
                              >Quoting the gcc documentation:
                              >>
                              > In this simple case, the ability to omit the middle operand is not
                              > especially useful. When it becomes useful is when the first
                              > operand does, or may (if it is a macro argument), contain a side
                              > effect. Then repeating the operand in the middle would perform
                              > the side effect twice. Omitting the middle operand uses the value
                              > already computed without the undesirable effects of recomputing
                              > it.
                              >
                              I don't find this very convincing. The usual reason for macros of this
                              kind is efficiency, and the usual reason for using them rather than
                              inline functions is portability to systems that don't provide them.
                              Since GCC does support inline functions, using a different GCC-specific
                              mechanism is pointless.
                              return foo() ? : bar;

                              It's not only about macros. Of course one always can introduce
                              a helper variable here and everything (of course one can use
                              standard C), that's another thing.

                              Yevgen

                              Comment

                              Working...