Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Lifetime of temporary objects
Forum Updated to NodeBB v4.3 + New Features

Lifetime of temporary objects

Scheduled Pinned Locked Moved Unsolved C++ Gurus
10 Posts 4 Posters 1.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JKSHJ JKSH

    @SimonSchroeder said in Convert QString pointer to char pointer ?:

    Under certain circumstance (which are still not clear to me) it is necessary to use a temporary variable for the QByteArray (and I assume it would be the same with std::string in the other solution).

    You must always store the intermediate data in a variable until you no longer need the char*. Otherwise, you end up with an invalid, dangling pointer which points to memory that has been freed.

    If you're lucky, you get a crash straight away so you know that something's wrong. If you're unlucky, you don't notice anything until much later.

    QString qstr = ...
    
    const char *p1 = qstr.toStdString().c_str(); // The std::string gets destroyed after this line
    // p1 is now a dangling pointer
    
    const char *p2 = qstr.toUtf8().constData(); // The QByteArray gets destroyed after this line
    // p2 is now a dangling pointer
    kshegunovK Offline
    kshegunovK Offline
    kshegunov
    Moderators
    wrote on last edited by JKSH
    #1

    Edit: This post is wrong. Disregard it.

    @JKSH said in Convert QString pointer to char pointer ?:

    const char *p2 = qstr.toUtf8().constData(); // The QByteArray gets destroyed after this line
    

    Correct, but it's usually more subtle than this. The temporary is valid just as long as the immediate evaluation takes place. The typical shoot-yourself-in-the-foot usage is:

    void someFunction(int a, char * x);
    
    ...
    QString z;
    someFunction(1, z.toUtf8().constData()); //< At the point the compiler pushes 1 to the stack the `z.toUtf8()` temporary had died already (assuming right-to-left argument evaluation like gcc does, I believe).
    

    Read and abide by the Qt Code of Conduct

    JonBJ fcarneyF 2 Replies Last reply
    0
    • kshegunovK kshegunov

      Edit: This post is wrong. Disregard it.

      @JKSH said in Convert QString pointer to char pointer ?:

      const char *p2 = qstr.toUtf8().constData(); // The QByteArray gets destroyed after this line
      

      Correct, but it's usually more subtle than this. The temporary is valid just as long as the immediate evaluation takes place. The typical shoot-yourself-in-the-foot usage is:

      void someFunction(int a, char * x);
      
      ...
      QString z;
      someFunction(1, z.toUtf8().constData()); //< At the point the compiler pushes 1 to the stack the `z.toUtf8()` temporary had died already (assuming right-to-left argument evaluation like gcc does, I believe).
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @kshegunov said in Convert QString pointer to char pointer ?:

      someFunction(1, z.toUtf8().constData()); //< At the point the compiler pushes 1 to the stack the z.toUtf8() temporary had died already (assuming right-to-left argument evaluation like gcc does, I believe).

      I thought "they" said something/somewhere the temporaries "last until the end of the expression/statement they are in. Or similar.

      You should back this claim up :) I was never keen on these "temporaries" being used in Qt (C++?), but if this is true they are "too dangerous" to dare using?!

      For example, you can't use two of them, presumably:

      someFunction(z.toUtf8().constData(), z2.toUtf8().constData());
      

      ?

      kshegunovK 1 Reply Last reply
      0
      • JonBJ JonB

        @kshegunov said in Convert QString pointer to char pointer ?:

        someFunction(1, z.toUtf8().constData()); //< At the point the compiler pushes 1 to the stack the z.toUtf8() temporary had died already (assuming right-to-left argument evaluation like gcc does, I believe).

        I thought "they" said something/somewhere the temporaries "last until the end of the expression/statement they are in. Or similar.

        You should back this claim up :) I was never keen on these "temporaries" being used in Qt (C++?), but if this is true they are "too dangerous" to dare using?!

        For example, you can't use two of them, presumably:

        someFunction(z.toUtf8().constData(), z2.toUtf8().constData());
        

        ?

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #3

        @JonB said in Convert QString pointer to char pointer ?:

        I thought "they" said something/somewhere the temporaries "last until the end of the expression/statement they are in.

        "They" would be correct, in the sense that expression ends with evaluating the argument for the function. Or in the above example - before putting 1 as the next entry in the stack.

        You should back this claim up

        Which claim? That gcc goes right to left? We tested that with @SGaist 2 years ago or thereabouts and we found that gcc and msvc does it the same, while clang goes left to right, if memory serves me. But in any case it's not that important here.

        I was never keen on these "temporaries" being used in Qt (C++?), but if this is true they are "too dangerous" to dare using?!

        Nothing to do with Qt, it's a C++ thing. And not if you keep track of what is what and don't return/dereference data from a temporary. Other typical and rather subtle cases of dangling references are also possible. Consider:

        class B;
        class A
        {
            A(B & b)
                : ref(b)
            {
            }
        
            B & ref;
        };
        

        When used like this:

        A a(B(...)); //< Oops, I did it again
        

        For example, you can't use two of them, presumably

        Not unless you like pain and suffering.

        Read and abide by the Qt Code of Conduct

        JonBJ 1 Reply Last reply
        0
        • kshegunovK kshegunov

          @JonB said in Convert QString pointer to char pointer ?:

          I thought "they" said something/somewhere the temporaries "last until the end of the expression/statement they are in.

          "They" would be correct, in the sense that expression ends with evaluating the argument for the function. Or in the above example - before putting 1 as the next entry in the stack.

          You should back this claim up

          Which claim? That gcc goes right to left? We tested that with @SGaist 2 years ago or thereabouts and we found that gcc and msvc does it the same, while clang goes left to right, if memory serves me. But in any case it's not that important here.

          I was never keen on these "temporaries" being used in Qt (C++?), but if this is true they are "too dangerous" to dare using?!

          Nothing to do with Qt, it's a C++ thing. And not if you keep track of what is what and don't return/dereference data from a temporary. Other typical and rather subtle cases of dangling references are also possible. Consider:

          class B;
          class A
          {
              A(B & b)
                  : ref(b)
              {
              }
          
              B & ref;
          };
          

          When used like this:

          A a(B(...)); //< Oops, I did it again
          

          For example, you can't use two of them, presumably

          Not unless you like pain and suffering.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @kshegunov
          [With apologies to the OP now that this hijacking is getting much larger than intended...]

          There must be something wrong in your analysis, surely, because the way you describe it/I understand what you describe, I can barely see any case/statement/expression in which you could dare to use this temporary.

          qDebug() << z.toUtf8().constData();
          // ^  Nope: who knows what serializing *might* do, creating temps of its own?
          somefunc(z.toUtf8().constData());
          // ^ Nope, again `somefunc()` could do anything before accessing the passed-in-temporary, messing it up?
          

          I think I am misunderstanding something about which is the temporary and what the behaviour is :( Can you supply one of your proper C++ references for this, so I can look it up and torture my brain, please?

          kshegunovK 1 Reply Last reply
          0
          • JonBJ JonB

            @kshegunov
            [With apologies to the OP now that this hijacking is getting much larger than intended...]

            There must be something wrong in your analysis, surely, because the way you describe it/I understand what you describe, I can barely see any case/statement/expression in which you could dare to use this temporary.

            qDebug() << z.toUtf8().constData();
            // ^  Nope: who knows what serializing *might* do, creating temps of its own?
            somefunc(z.toUtf8().constData());
            // ^ Nope, again `somefunc()` could do anything before accessing the passed-in-temporary, messing it up?
            

            I think I am misunderstanding something about which is the temporary and what the behaviour is :( Can you supply one of your proper C++ references for this, so I can look it up and torture my brain, please?

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @JonB said in Convert QString pointer to char pointer ?:

            There must be something wrong in your analysis, surely

            Indeed, I'm wrong (about my first post); the last one (with keeping the reference is correct).

            @JonB said in Convert QString pointer to char pointer ?:

            Can you supply one of your proper C++ references for this, so I can look it up and torture my brain, please?

            https://timsong-cpp.github.io/cppwp/n3337/class.temporary

            Read and abide by the Qt Code of Conduct

            JonBJ 1 Reply Last reply
            1
            • kshegunovK kshegunov

              @JonB said in Convert QString pointer to char pointer ?:

              There must be something wrong in your analysis, surely

              Indeed, I'm wrong (about my first post); the last one (with keeping the reference is correct).

              @JonB said in Convert QString pointer to char pointer ?:

              Can you supply one of your proper C++ references for this, so I can look it up and torture my brain, please?

              https://timsong-cpp.github.io/cppwp/n3337/class.temporary

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @kshegunov
              I read and tried to understand that reference, and it was about as impenetrable as expected for C++.

              Are you still sticking by your:

              someFunction(1, z.toUtf8().constData()); //< At the point the compiler pushes 1 to the stack the `z.toUtf8()` temporary had died already (assuming right-to-left argument evaluation like gcc does, I believe).
              

              If so, where you do you see in the reference something mentioning/explaining that the apparent "full expression" scope before temporary object deletion applies in this case (among parameters), please?

              kshegunovK 1 Reply Last reply
              0
              • JonBJ JonB

                @kshegunov
                I read and tried to understand that reference, and it was about as impenetrable as expected for C++.

                Are you still sticking by your:

                someFunction(1, z.toUtf8().constData()); //< At the point the compiler pushes 1 to the stack the `z.toUtf8()` temporary had died already (assuming right-to-left argument evaluation like gcc does, I believe).
                

                If so, where you do you see in the reference something mentioning/explaining that the apparent "full expression" scope before temporary object deletion applies in this case (among parameters), please?

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #7

                @JonB said in Convert QString pointer to char pointer ?:

                Are you still sticking by your

                No. I did write that I was wrong, didn't I?

                Read and abide by the Qt Code of Conduct

                JonBJ 1 Reply Last reply
                1
                • kshegunovK kshegunov

                  @JonB said in Convert QString pointer to char pointer ?:

                  Are you still sticking by your

                  No. I did write that I was wrong, didn't I?

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @kshegunov
                  I didn't know you were referring to that. I'm glad, because it would be worrying to me if it behaved like that.

                  1 Reply Last reply
                  0
                  • kshegunovK kshegunov

                    Edit: This post is wrong. Disregard it.

                    @JKSH said in Convert QString pointer to char pointer ?:

                    const char *p2 = qstr.toUtf8().constData(); // The QByteArray gets destroyed after this line
                    

                    Correct, but it's usually more subtle than this. The temporary is valid just as long as the immediate evaluation takes place. The typical shoot-yourself-in-the-foot usage is:

                    void someFunction(int a, char * x);
                    
                    ...
                    QString z;
                    someFunction(1, z.toUtf8().constData()); //< At the point the compiler pushes 1 to the stack the `z.toUtf8()` temporary had died already (assuming right-to-left argument evaluation like gcc does, I believe).
                    
                    fcarneyF Offline
                    fcarneyF Offline
                    fcarney
                    wrote on last edited by
                    #9

                    @kshegunov said in Lifetime of temporary objects:

                    Edit: This post is wrong. Disregard it.

                    Object existential crisis averted!

                    I just ignored the rest of the post and had to comment.

                    C++ is a perfectly valid school of magic.

                    1 Reply Last reply
                    0
                    • Kent-DorfmanK Offline
                      Kent-DorfmanK Offline
                      Kent-Dorfman
                      wrote on last edited by
                      #10

                      Hmmm...a bit of existential-niahlistist-objectivism

                      1 Reply Last reply
                      2

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved