Re: Problem "taking address of temporary"

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • James Kanze

    Re: Problem "taking address of temporary"

    On Nov 18, 5:50 pm, Pete Becker <p...@versatile coding.comwrote :
    On 2008-11-18 10:52:48 -0500, Andy Gibbs <andyg1...@hotm ail.co.uksaid:
    The problem comes in the line "Function(&Test ("test2"));"
    with the warning "taking address of temporary". I am using
    GCC 4.1.2. However, the code runs as expected with the
    following output:
    test1:
    ctor
    str=test1
    dtor
    test2:
    ctor
    str=test2
    dtor
    test3
    null
    The code above demonstrates that the Test object is not
    destroyed until after Function is called, so I cannot see
    why the compiler complains about this.
    The compiler warns about it because the code takes the address
    of a temporary, although there's nothing inherently wrong with
    doing that.
    Has this changed in the latest draft. According to my copy of
    the standard (version 1998---out of date, I know), "The
    operand [of the unary & operator] shall be an lvalue or a
    qualified-id". His expression was &Test("test2 "); IMHO, the
    compiler generated a warning because it was being laxist.

    If I compile his code with Sun CC, I get:
    "addrtemp.c c", line 34: Warning, badargtypel2w: String literal
    converted to char* in formal argument str in call to Test::Test
    (char*).
    "addrtemp.c c", line 37: Warning, badargtypel2w: String literal
    converted to char* in formal argument str in call to Test::Test
    (char*).
    "addrtemp.c c", line 37: Error, wantvarname: The "&" operator can
    only be applied to a variable or other l-value.
    Which is what I'd expect from a good compiler. Curiously
    enough, g++ only generates says:
    addrtemp.cc: In function 'int main(int, char**)':
    addrtemp.cc:37: warning: taking address of temporary
    even with -std=c++98 -pedantic (I'd call this a bug), and VC++
    doesn't say anything.
    If you misuse the result you can get in trouble. Apparently
    the writers of your compiler thnk that you can't be trusted to
    use that address without screwing up.
    Apparently, the writers of his compiler don't care about the
    standard. (Nothing new there.) And it's the members of the
    stadnards committee who think you can't be trusted. (Or just
    wanted to remain compatible with C in this respect.)

    --
    James Kanze (GABI Software) email:james.kan ze@gmail.com
    Conseils en informatique orientée objet/
    Beratung in objektorientier ter Datenverarbeitu ng
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  • Victor Bazarov

    #2
    Re: Problem &quot;taking address of temporary&quot;

    James Kanze wrote:
    On Nov 18, 5:50 pm, Pete Becker <p...@versatile coding.comwrote :
    >On 2008-11-18 10:52:48 -0500, Andy Gibbs <andyg1...@hotm ail.co.uksaid:
    >>The problem comes in the line "Function(&Test ("test2"));"
    >>with the warning "taking address of temporary". I am using
    >>GCC 4.1.2. However, the code runs as expected with the
    >>following output:
    >
    >>test1:
    >>ctor
    >>str=test1
    >>dtor
    >>test2:
    >>ctor
    >>str=test2
    >>dtor
    >>test3
    >>null
    >
    >>The code above demonstrates that the Test object is not
    >>destroyed until after Function is called, so I cannot see
    >>why the compiler complains about this.
    >
    >The compiler warns about it because the code takes the address
    >of a temporary, although there's nothing inherently wrong with
    >doing that.
    >
    Has this changed in the latest draft. According to my copy of
    the standard (version 1998---out of date, I know), "The
    operand [of the unary & operator] shall be an lvalue or a
    qualified-id". His expression was &Test("test2 "); IMHO, the
    compiler generated a warning because it was being laxist.
    [..]
    There is an inherent controversy around this. Example:

    struct Foo {
    Foo(int) {}
    Foo& that() { return *this; }
    };

    int main() {
    Foo(42); // expression that yields an rvalue
    Foo(42).that(); // expression that is an lvalue
    }

    How would you explain that? :-) You can't avoid being "laxist" with the
    language that contains such pearls.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • Andrey Tarasevich

      #3
      Re: Problem &quot;taking address of temporary&quot;

      Victor Bazarov wrote:
      >
      There is an inherent controversy around this. Example:
      >
      struct Foo {
      Foo(int) {}
      Foo& that() { return *this; }
      };
      >
      int main() {
      Foo(42); // expression that yields an rvalue
      Foo(42).that(); // expression that is an lvalue
      }
      >
      How would you explain that? :-) You can't avoid being "laxist" with the
      language that contains such pearls.
      ...
      There's an inherent controversy around everything, if you dig deep
      enough. Your example is not really different from, say

      const int* addr(const int& i) { return &i; }

      int main() {
      const int* p = addr(42);
      }

      You think this is a "pearl"? I'd say this is just a necessary evil one
      has to remember about.

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • Pete Becker

        #4
        Re: Problem &quot;taking address of temporary&quot;

        On 2008-11-18 12:24:01 -0500, James Kanze <james.kanze@gm ail.comsaid:
        On Nov 18, 5:50 pm, Pete Becker <p...@versatile coding.comwrote :
        >On 2008-11-18 10:52:48 -0500, Andy Gibbs <andyg1...@hotm ail.co.uksaid:
        >>The problem comes in the line "Function(&Test ("test2"));"
        >>with the warning "taking address of temporary". I am using
        >>GCC 4.1.2. However, the code runs as expected with the
        >>following output:
        >
        >>test1:
        >>ctor
        >>str=test1
        >>dtor
        >>test2:
        >>ctor
        >>str=test2
        >>dtor
        >>test3
        >>null
        >
        >>The code above demonstrates that the Test object is not
        >>destroyed until after Function is called, so I cannot see
        >>why the compiler complains about this.
        >
        >The compiler warns about it because the code takes the address
        >of a temporary, although there's nothing inherently wrong with
        >doing that.
        >
        Has this changed in the latest draft. According to my copy of
        the standard (version 1998---out of date, I know), "The
        operand [of the unary & operator] shall be an lvalue or a
        qualified-id". His expression was &Test("test2 "); IMHO, the
        compiler generated a warning because it was being laxist.
        No, it hasn't changed. I was being lax. Thanks for pointing it out.

        --
        Pete
        Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
        Standard C++ Library Extensions: a Tutorial and Reference
        (www.petebecker.com/tr1book)

        Comment

        • James Kanze

          #5
          Re: Problem &quot;taking address of temporary&quot;

          On Nov 18, 6:53 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
          James Kanze wrote:
          [...]
          The compiler warns about it because the code takes the
          address of a temporary, although there's nothing inherently
          wrong with doing that.
          Has this changed in the latest draft.  According to my copy of
          the standard (version 1998---out of date, I know), "The
          operand [of the unary & operator] shall be an lvalue or a
          qualified-id".  His expression was &Test("test2 "); IMHO, the
          compiler generated a warning because it was being laxist.
          [..]
          There is an inherent controversy around this.  Example:
              struct Foo {
                  Foo(int) {}
                  Foo& that() { return *this; }
              };
              int main() {
                 Foo(42);        // expression that yields an rvalue
                 Foo(42).that(); // expression that is an lvalue
              }
          How would you explain that? :-)
          I wouldn't try to:-). But the language standard defines a
          concept of lvalue and rvalue, or at least insists that they
          exist, that certain expressions return lvalues, others rvalues,
          and that certain operators require lvalues, others rvalues (and
          that there is an lvalue to rvalue conversion---so that in
          something like i=j, where both i and j have type int, there is
          an implicit conversion involved). The language says that the
          expression Test("test1") is an rvalue, and it says that unary &
          requires an lvalue, and so be it.
          You can't avoid being "laxist" with the language that contains
          such pearls.
          Such "pearls" are probably inevitable as soon as you try to
          maintain the distinction between lvalues and rvalues, and also
          have real objects. (At one point, I actually suggested that we
          drop the concept of lvalue/rvalue completely, and simply state
          that all temporaries were considered const. This would have
          allowed things like &3, with type int const, but after all, we
          allow this indirectly already, if you bind 3 to a const
          reference, and then take its address.)

          --
          James Kanze (GABI Software) email:james.kan ze@gmail.com
          Conseils en informatique orientée objet/
          Beratung in objektorientier ter Datenverarbeitu ng
          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

          Comment

          Working...