What do you expect this to print?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Steven T. Hatton

    What do you expect this to print?

    What should I expect the following code to print? Is it defined in the
    Standard? What does it produce for you? I was kind of surprised by what
    GCC 4.0.2 made of it.

    #include <string>
    #include <iostream>

    typedef std::string object;

    class arrow{
    public:
    arrow(object& domain_
    ,object& codomain_
    ,const std::string& name_)
    :_domain(domain _)
    ,_codomain(codo main_)
    ,_name(name_)
    {
    std::cout << _name << std::endl;
    }

    object domain(){ return _domain; }
    object codomain(){ return _codomain; }

    operator object () { return _codomain; }

    std::ostream& print(std::ostr eam& out) const {
    return out<<_domain<<"--"<<_name<<"->"<<_codomain ;
    }

    private:
    object _domain;
    object _codomain;
    const std::string& _name;
    };

    std::ostream& operator<<(std: :ostream& out, const arrow& a ){
    return a.print(out);
    }

    int main(){
    object a("a");
    object b("b");
    arrow f(a,b,"f");
    std::cout << f << std::endl;
    }

    --
    NOUN:1. Money or property bequeathed to another by will. 2. Something handed
    down from an ancestor or a predecessor or from the past: a legacy of
    religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
    from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
  • paulius-maruska

    #2
    Re: What do you expect this to print?

    Steven T. Hatton wrote:[color=blue]
    > What should I expect the following code to print? Is it defined in the
    > Standard? What does it produce for you? I was kind of surprised by what
    > GCC 4.0.2 made of it.[/color]
    As expected, it outputs:
    f
    a--->b

    However, if you change _name member from const std::string& to
    std::string it produces:
    f
    a--f->b

    (Again - as expected).

    Comment

    • Alf P. Steinbach

      #3
      Re: What do you expect this to print?

      * Steven T. Hatton:[color=blue]
      > What should I expect the following code to print? Is it defined in the
      > Standard?[/color]

      It's Undefined Behavior.

      [color=blue]
      > What does it produce for you? I was kind of surprised by what
      > GCC 4.0.2 made of it.
      >
      > #include <string>
      > #include <iostream>
      >
      > typedef std::string object;
      >
      > class arrow{
      > public:
      > arrow(object& domain_
      > ,object& codomain_
      > ,const std::string& name_)
      > :_domain(domain _)
      > ,_codomain(codo main_)
      > ,_name(name_)[/color]

      Binding a reference to a temporary is only OK as long as that temporary
      persists.

      [color=blue]
      > {
      > std::cout << _name << std::endl;
      > }
      >
      > object domain(){ return _domain; }
      > object codomain(){ return _codomain; }
      >
      > operator object () { return _codomain; }
      >
      > std::ostream& print(std::ostr eam& out) const {
      > return out<<_domain<<"--"<<_name<<"->"<<_codomain ;
      > }
      >
      > private:
      > object _domain;
      > object _codomain;
      > const std::string& _name;[/color]

      Remove the 'const' and especially the '&' and you'll be okay.

      Possibly you thought that binding a reference to const to a temporary
      magically makes that temporary persist.

      That's only for a local reference, and it's actually a bit more subtle
      (formally a new temporary is created with lifetime extended to the scope of
      the reference, and the initializer rvalue is copied to that temporary).

      --
      A: Because it messes up the order in which people normally read text.
      Q: Why is it such a bad thing?
      A: Top-posting.
      Q: What is the most annoying thing on usenet and in e-mail?

      Comment

      • Zara

        #4
        Re: What do you expect this to print?

        On Tue, 25 Oct 2005 05:32:46 -0400, "Steven T. Hatton"
        <chattengau@ger mania.sup> wrote:
        [color=blue]
        >What should I expect the following code to print? Is it defined in the
        >Standard? What does it produce for you? I was kind of surprised by what
        >GCC 4.0.2 made of it.
        >[/color]
        (...)[color=blue]
        >class arrow{
        >public:
        > arrow(object& domain_
        > ,object& codomain_
        > ,const std::string& name_)
        > :_domain(domain _)
        > ,_codomain(codo main_)
        > ,_name(name_)
        > {
        > std::cout << _name << std::endl;
        > }
        >[/color]
        (...)[color=blue]
        >private:
        > object _domain;
        > object _codomain;
        > const std::string& _name;
        >};
        >[/color]
        (...)[color=blue]
        >
        >int main(){
        > object a("a");
        > object b("b");
        > arrow f(a,b,"f");
        > std::cout << f << std::endl;
        >}[/color]

        The result is undefined.

        You are initialising a temporary string with "f", then assigning a
        reference to it (_name). After f ceration, the temporary disappears
        (=is not longer valid), and you have an invalid reference.



        Comment

        • Steven T. Hatton

          #5
          Re: What do you expect this to print?

          Alf P. Steinbach wrote:
          [color=blue]
          > * Steven T. Hatton:[color=green]
          >> What should I expect the following code to print? Is it defined in the
          >> Standard?[/color]
          >
          > It's Undefined Behavior.
          >
          >[color=green]
          >> What does it produce for you? I was kind of surprised by what
          >> GCC 4.0.2 made of it.
          >>
          >> #include <string>
          >> #include <iostream>
          >>
          >> typedef std::string object;
          >>
          >> class arrow{
          >> public:
          >> arrow(object& domain_
          >> ,object& codomain_
          >> ,const std::string& name_)
          >> :_domain(domain _)
          >> ,_codomain(codo main_)
          >> ,_name(name_)[/color]
          >
          > Binding a reference to a temporary is only OK as long as that temporary
          > persists.[/color]

          As I suspected.
          [color=blue]
          >[color=green]
          >> {
          >> std::cout << _name << std::endl;
          >> }
          >>
          >> object domain(){ return _domain; }
          >> object codomain(){ return _codomain; }
          >>
          >> operator object () { return _codomain; }
          >>
          >> std::ostream& print(std::ostr eam& out) const {
          >> return out<<_domain<<"--"<<_name<<"->"<<_codomain ;
          >> }
          >>
          >> private:
          >> object _domain;
          >> object _codomain;
          >> const std::string& _name;[/color]
          >
          > Remove the 'const' and especially the '&' and you'll be okay.[/color]

          Indeed.
          [color=blue]
          > Possibly you thought that binding a reference to const to a temporary
          > magically makes that temporary persist.[/color]

          I really hadn't thought about it until I did it. It was just toy code I was
          using to try and reason out some obtuse mathematical language.
          [color=blue]
          > That's only for a local reference, and it's actually a bit more subtle
          > (formally a new temporary is created with lifetime extended to the scope
          > of the reference, and the initializer rvalue is copied to that temporary).[/color]

          I guess I had intuitively expected the temporary to outlive its scope in
          that case. I'm glad I messed it up in that situation rather than in
          serious code. I suspect that behavior varies from compiler (version) to
          compiler (version).

          --
          NOUN:1. Money or property bequeathed to another by will. 2. Something handed
          down from an ancestor or a predecessor or from the past: a legacy of
          religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
          from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/

          Comment

          • Steven T. Hatton

            #6
            Re: What do you expect this to print?

            paulius-maruska wrote:
            [color=blue]
            > Steven T. Hatton wrote:[color=green]
            >> What should I expect the following code to print? Is it defined in the
            >> Standard? What does it produce for you? I was kind of surprised by what
            >> GCC 4.0.2 made of it.[/color]
            > As expected, it outputs:
            > f
            > a--->b[/color]

            Is the first 'f' required by law? I suspect not. That is to say, I suspect
            the scope of the temporary is actually the argument list. Even that may be
            overstating things since I don't believe the value of the actual parameter
            has a specified state vis-a-vis other actual parameters in the same
            function call.

            --
            NOUN:1. Money or property bequeathed to another by will. 2. Something handed
            down from an ancestor or a predecessor or from the past: a legacy of
            religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
            from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/

            Comment

            Working...