Scope of temporary variables

Discussion in 'C++' started by gerald.dalley@gmail.com, Oct 9, 2006.

  1. Guest

    I've been trying to pin down the scoping rules for temporary variables
    in C++. I know that doing something like:

    string s("abc");
    const char *t = (s+"def").c_str();
    cout << t;

    is invalid since (s+"def") creates a temporary which goes out of scope,
    thus leaving t a dangling pointer. What I'm wondering is whether
    temporaries go out of scope when their expression terminates or when
    their statement terminates. For example, is the following wrong?

    string s("abc");
    cout << (s+"def").c_str();
     
    , Oct 9, 2006
    #1
    1. Advertising

  2. Kai-Uwe Bux Guest

    wrote:

    > I've been trying to pin down the scoping rules for temporary variables
    > in C++. I know that doing something like:
    >
    > string s("abc");
    > const char *t = (s+"def").c_str();
    > cout << t;
    >
    > is invalid since (s+"def") creates a temporary which goes out of scope,
    > thus leaving t a dangling pointer. What I'm wondering is whether
    > temporaries go out of scope when their expression terminates or when
    > their statement terminates.


    If I recall correctly, the scope is the largest expression of which the
    temporary is a subexpression. (And then there was something about function
    calls).

    > For example, is the following wrong?
    >
    > string s("abc");
    > cout << (s+"def").c_str();


    That would be fine since 'cout << (s+"def").c_str()' is an expression.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Oct 10, 2006
    #2
    1. Advertising

  3. Guest

    Kai-Uwe Bux wrote:
    > wrote:
    >
    > > I've been trying to pin down the scoping rules for temporary variables
    > > in C++. I know that doing something like:
    > >
    > > string s("abc");
    > > const char *t = (s+"def").c_str();
    > > cout << t;
    > >
    > > is invalid since (s+"def") creates a temporary which goes out of scope,
    > > thus leaving t a dangling pointer. What I'm wondering is whether
    > > temporaries go out of scope when their expression terminates or when
    > > their statement terminates.

    >
    > If I recall correctly, the scope is the largest expression of which the
    > temporary is a subexpression. (And then there was something about function
    > calls).
    >
    > > For example, is the following wrong?
    > >
    > > string s("abc");
    > > cout << (s+"def").c_str();

    >
    > That would be fine since 'cout << (s+"def").c_str()' is an expression.
    >
    >
    > Best
    >
    > Kai-Uwe Bux


    Good point. I guess I should really ask it in function-call form:
    string s("abc");
    printf("%s\n", (s+"def").c_str());
     
    , Oct 10, 2006
    #3
  4. Kai-Uwe Bux Guest

    wrote:

    > Kai-Uwe Bux wrote:
    >> wrote:
    >>
    >> > I've been trying to pin down the scoping rules for temporary variables
    >> > in C++. I know that doing something like:
    >> >
    >> > string s("abc");
    >> > const char *t = (s+"def").c_str();
    >> > cout << t;
    >> >
    >> > is invalid since (s+"def") creates a temporary which goes out of scope,
    >> > thus leaving t a dangling pointer. What I'm wondering is whether
    >> > temporaries go out of scope when their expression terminates or when
    >> > their statement terminates.

    >>
    >> If I recall correctly, the scope is the largest expression of which the
    >> temporary is a subexpression. (And then there was something about
    >> function calls).
    >>
    >> > For example, is the following wrong?
    >> >
    >> > string s("abc");
    >> > cout << (s+"def").c_str();

    >>
    >> That would be fine since 'cout << (s+"def").c_str()' is an expression.
    >>
    >>
    >> Best
    >>
    >> Kai-Uwe Bux

    >
    > Good point. I guess I should really ask it in function-call form:
    > string s("abc");
    > printf("%s\n", (s+"def").c_str());


    I think, 'printf("%s\n", (s+"def").c_str())' is an expression, too. It
    happens to be of type void. Generally, in C++, a function call is just a
    special form of expression. The statement is, again, an expression
    statement and the function is just called in the course of evaluating the
    expression (which, somewhat strangely, can be of type void!).

    In other words, you should be fine here, too.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Oct 10, 2006
    #4
  5. Kai-Uwe Bux wrote:
    > [..]
    > I think, 'printf("%s\n", (s+"def").c_str())' is an expression, too. It
    > happens to be of type void. [..]


    Close. It's of type 'int'. 'printf' "returns the number of characters
    transmitted or a negative value if an output or encoding error occurred".

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 10, 2006
    #5
  6. shaanxxx Guest

    wrote:
    > I've been trying to pin down the scoping rules for temporary variables
    > in C++. I know that doing something like:
    >
    > string s("abc");
    > const char *t = (s+"def").c_str();
    > cout << t;
    >
    > is invalid since (s+"def") creates a temporary which goes out of scope,
    > thus leaving t a dangling pointer. What I'm wondering is whether
    > temporaries go out of scope when their expression terminates or when
    > their statement terminates. For example, is the following wrong?
    >
    > string s("abc");
    > cout << (s+"def").c_str();


    scope would be the block in which is defined.
     
    shaanxxx, Oct 10, 2006
    #6
  7. shaanxxx Guest

    wrote:
    > I've been trying to pin down the scoping rules for temporary variables
    > in C++. I know that doing something like:
    >
    > string s("abc");
    > const char *t = (s+"def").c_str();
    > cout << t;
    >
    > is invalid since (s+"def") creates a temporary which goes out of scope,
    > thus leaving t a dangling pointer. What I'm wondering is whether
    > temporaries go out of scope when their expression terminates or when
    > their statement terminates. For example, is the following wrong?
    >
    > string s("abc");
    > cout << (s+"def").c_str();


    scope of temporaries would be the block in which temporaries are
    defined.
     
    shaanxxx, Oct 10, 2006
    #7
  8. Guest

    shaanxxx wrote:
    > wrote:
    > > I've been trying to pin down the scoping rules for temporary variables
    > > in C++. I know that doing something like:
    > >
    > > string s("abc");
    > > const char *t = (s+"def").c_str();
    > > cout << t;
    > >
    > > is invalid since (s+"def") creates a temporary which goes out of scope,
    > > thus leaving t a dangling pointer. What I'm wondering is whether
    > > temporaries go out of scope when their expression terminates or when
    > > their statement terminates. For example, is the following wrong?
    > >
    > > string s("abc");
    > > cout << (s+"def").c_str();

    >
    > scope of temporaries would be the block in which temporaries are
    > defined.


    I'm pretty sure the scoping of temporaries is tighter than block level.
    The following code:

    class dstring : public string
    {
    public:
    dstring(const char *s) : string(s), i(n++) {};
    dstring(string const &s) : string(s), i(n++) {};
    virtual ~dstring() { cout << "dstring " << i << " destructing\n";
    }
    dstring operator+(const char *s) { return dstring((string)*this +
    s); }
    private:
    int i;
    static int n;
    };
    int dstring::n = 0;

    void dstringTests()
    {
    const char *t = (dstring("abc") + "def").c_str();
    printf("t = '%s'\n\n", t);

    printf("inlined = '%s'\n", (dstring("abc") + "def").c_str());
    printf("\n");

    printf("inlined#2 = '%s'\n", (dstring("abc") + "def").c_str());
    printf("\n");
    }

    outputs:

    dstring 1 destructing
    dstring 0 destructing
    t = ''

    inlined = 'abcdef'
    dstring 3 destructing
    dstring 2 destructing

    inlined#2 = 'abcdef'
    dstring 5 destructing
    dstring 4 destructing

    If the scoping of temporaries was block-level, none of the "dstring x
    destructing" lines would be printed until after the "x = y" lines.
    These results are for VS2005, g++ 3.3.5, and g++ 3.4.4, with and
    without optimizations.
     
    , Oct 10, 2006
    #8
  9. dasjotre Guest

    shaanxxx wrote:
    > scope of temporaries would be the block in which temporaries are
    > defined.


    Not correct:
    "Unless bound to a reference or used to initialize a named
    object, a temporary object is destroyed at the end of the
    full expression in which it was created." [Stroustrup]

    that is in:

    const char *t = (s+"def").c_str();

    the temp string created from s+"def" is destroyed at ';'
     
    dasjotre, Oct 10, 2006
    #9
  10. dasjotre wrote:
    > shaanxxx wrote:
    > > scope of temporaries would be the block in which temporaries are
    > > defined.

    >
    > Not correct:
    > "Unless bound to a reference or used to initialize a named
    > object, a temporary object is destroyed at the end of the
    > full expression in which it was created." [Stroustrup]
    >
    > that is in:
    >
    > const char *t = (s+"def").c_str();
    >
    > the temp string created from s+"def" is destroyed at ';'


    Thanks. That's exactly what I was looking for.
     
    Gerald Dalley, Oct 10, 2006
    #10
  11. shaanxxx posted:

    > scope of temporaries would be the block in which temporaries are
    > defined.



    Please refrain from posting absolute bullshit.

    Temporaries are destroyed at the next semi-colon.

    This causes a slight problem if you have something like:

    x++, Func(x);

    If "x" is a built-in type, then this is fine because there's a sequence point
    between each side of the comma.

    If "x" is a user-defined type, however, then you'll have a problem if you use
    the "proxy method" of postincrementing your object, because the temporary
    will be destroyed at then end of the statement, rather than before the next
    side of the comma.

    --

    Frederick Gotham
     
    Frederick Gotham, Oct 10, 2006
    #11
  12. Alan Johnson Guest

    wrote:
    > I've been trying to pin down the scoping rules for temporary variables
    > in C++. I know that doing something like:
    >
    > string s("abc");
    > const char *t = (s+"def").c_str();
    > cout << t;
    >
    > is invalid since (s+"def") creates a temporary which goes out of scope,
    > thus leaving t a dangling pointer. What I'm wondering is whether
    > temporaries go out of scope when their expression terminates or when
    > their statement terminates. For example, is the following wrong?
    >
    > string s("abc");
    > cout << (s+"def").c_str();


    Scope is a property of names, and since a temporary doesn't have a
    name, it doesn't have a scope.

    What you are asking about is lifetime.

    The other responses in this thread do a good job of answering your
    question.

    --
    Alan Johnson
     
    Alan Johnson, Oct 12, 2006
    #12
  13. shaanxxx Guest

    Frederick Gotham wrote:
    > shaanxxx posted:
    >
    > > scope of temporaries would be the block in which temporaries are
    > > defined.

    >
    > Please refrain from posting absolute bullshit.

    Thanks for correction. I would appreciate if you can use better word.
    >
    > Temporaries are destroyed at the next semi-colon.
    >
    > This causes a slight problem if you have something like:
    >
    > x++, Func(x);
    >
    > If "x" is a built-in type, then this is fine because there's a sequence point
    > between each side of the comma.
    >
    > If "x" is a user-defined type, however, then you'll have a problem if you use
    > the "proxy method" of postincrementing your object, because the temporary
    > will be destroyed at then end of the statement, rather than before the next
    > side of the comma.
    >
    > --
    >
    > Frederick Gotham
     
    shaanxxx, Oct 14, 2006
    #13
  14. shaanxxx posted:

    > Thanks for correction. I would appreciate if you can use better word.


    Let's make a deal:

    (1) I'll use a better word if

    (2) You make sure you post correct info.

    --

    Frederick Gotham
     
    Frederick Gotham, Oct 15, 2006
    #14
  15. shaanxxx Guest

    Frederick Gotham wrote:
    > shaanxxx posted:
    >
    > > Thanks for correction. I would appreciate if you can use better word.

    >
    > Let's make a deal:
    >
    > (1) I'll use a better word if
    >
    > (2) You make sure you post correct info.
    >
    > --
    >
    > Frederick Gotham


    deal, You are appreciated.
    But I have seen people quoting wrong, replies what they get are good
    and corrective.
     
    shaanxxx, Oct 15, 2006
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul Opal
    Replies:
    12
    Views:
    1,003
    Paul Opal
    Oct 11, 2004
  2. ann
    Replies:
    13
    Views:
    694
    Patricia Shanahan
    Sep 13, 2005
  3. Edward Elliott

    temporary scope change

    Edward Elliott, Apr 19, 2006, in forum: Python
    Replies:
    2
    Views:
    292
    Edward Elliott
    Apr 19, 2006
  4. Replies:
    7
    Views:
    3,326
    James Kanze
    Feb 12, 2008
  5. Talha Oktay
    Replies:
    8
    Views:
    228
Loading...

Share This Page