Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. The Lounge
  4. In the news: GCC 6 breaks Qt 5
Qt 6.11 is out! See what's new in the release blog

In the news: GCC 6 breaks Qt 5

Scheduled Pinned Locked Moved The Lounge
14 Posts 3 Posters 7.6k Views 4 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.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    Reading the news I stumbled over the GCC 6 Release Series Changes and amongst other stuff it says this:

    Value range propagation now assumes that the this pointer of C++ member functions is non-null. This eliminates common null pointer checks but also breaks some non-conforming code-bases (such as Qt-5, Chromium, KDevelop). As a temporary work-around -fno-delete-null-pointer-checks can be used. Wrong code can be identified by using -fsanitize=undefined.

    So I was like "WTF?". Any comments on this?

    kshegunovK 1 Reply Last reply
    0
    • Chris KawaC Online
      Chris KawaC Online
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      I think this is already fixed (development list), or at least people are aware of it.

      1 Reply Last reply
      1
      • ? A Former User

        Reading the news I stumbled over the GCC 6 Release Series Changes and amongst other stuff it says this:

        Value range propagation now assumes that the this pointer of C++ member functions is non-null. This eliminates common null pointer checks but also breaks some non-conforming code-bases (such as Qt-5, Chromium, KDevelop). As a temporary work-around -fno-delete-null-pointer-checks can be used. Wrong code can be identified by using -fsanitize=undefined.

        So I was like "WTF?". Any comments on this?

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

        It would be interesting how the heck you end up with a null this ... the only case I could think of would be calling a method with a null pointer ...

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply
        0
        • Chris KawaC Online
          Chris KawaC Online
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #4

          the only case I could think of would be calling a method with a null pointer ...

          AFAIK this is undefined behavior in the standard and undefined behavior means it might actually work (i.e. compile and run without crashing), so a check for null this pointer could be used as a defense against such undefined behavior.

          The other example I can come up with is something like this:

          void killIt(Foo** ptr) { delete *ptr; *ptr = nullptr; }
          
          Bar::method()
          {
             killIt(this); //this would realistically be hidden deep inside a pile of function calls
             //this is now null
          }
          

          All this is of course evil on oh so many levels so I treat it as a contrived example.

          kshegunovK 1 Reply Last reply
          0
          • Chris KawaC Chris Kawa

            the only case I could think of would be calling a method with a null pointer ...

            AFAIK this is undefined behavior in the standard and undefined behavior means it might actually work (i.e. compile and run without crashing), so a check for null this pointer could be used as a defense against such undefined behavior.

            The other example I can come up with is something like this:

            void killIt(Foo** ptr) { delete *ptr; *ptr = nullptr; }
            
            Bar::method()
            {
               killIt(this); //this would realistically be hidden deep inside a pile of function calls
               //this is now null
            }
            

            All this is of course evil on oh so many levels so I treat it as a contrived example.

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

            @Chris-Kawa

            AFAIK this is undefined behavior in the standard

            Quite possible. Although I personally see no problem with calling methods with null pointers, or null this in general. It's reflection of the closeness of C++ to the hardware. Methods are oblivious to this if you consider the assembly.

            The other example I can come up with is something like this

            But I don't see any difference if you set the pointer to null, or the object just commits suicide and leaves a dangling pointer:

            Bar::method()
            {
                delete this;
                // this is now pointing to a very bad place
            }
            

            and as far as know (but don't hold me to it) the last snippet is allowed ... and if you ask me, it should be allowed ...

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • Chris KawaC Online
              Chris KawaC Online
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by
              #6

              delete this is quite useful and allowed. No problem there. The difference is that my example is more like

              Bar::method()
              {
                  delete this;
                  this = nullptr;
              }
              

              I think the reason calling methods on null pointers is undefined behavior, is that it is almost always a bug and not intended behavior. On the other hand, as you said, "this" is meaningless for the low level machine, so imposing any standard dictated runtime checks would be a wasteful overhead. So checking is bad and not checking is (usually) bad -> undefined behavior is the only sane thing to do in the standard.

              I personally see no problem with calling methods with null pointers

              I guess it's a language design decision. Calling a method without an instance is what static methods are for. If nulls were explicitly allowed in non-static methods you would have if(!this) return; or similar on top of virtually every method out there. That would be horrible.

              kshegunovK 1 Reply Last reply
              0
              • Chris KawaC Chris Kawa

                delete this is quite useful and allowed. No problem there. The difference is that my example is more like

                Bar::method()
                {
                    delete this;
                    this = nullptr;
                }
                

                I think the reason calling methods on null pointers is undefined behavior, is that it is almost always a bug and not intended behavior. On the other hand, as you said, "this" is meaningless for the low level machine, so imposing any standard dictated runtime checks would be a wasteful overhead. So checking is bad and not checking is (usually) bad -> undefined behavior is the only sane thing to do in the standard.

                I personally see no problem with calling methods with null pointers

                I guess it's a language design decision. Calling a method without an instance is what static methods are for. If nulls were explicitly allowed in non-static methods you would have if(!this) return; or similar on top of virtually every method out there. That would be horrible.

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

                @Chris-Kawa

                No problem there. The difference is that my example is more like ...

                Sure! However, while this'd look quite awkward syntactically the semantics is quite the same: this is pointing to an invalid location. That's what seems strange to me in the referred GCC change. As I see it, no checks are needed, especially for handling some quite obscure bug in code, it's just our responsibility as programmers to do better than that.

                I think the reason calling methods on null pointers is undefined behavior, is that it is almost always a bug and not intended behavior. On the other hand, as you said, "this" is meaningless for the low level machine, so imposing any standard dictated runtime checks would be a wasteful overhead. So checking is bad and not checking is (usually) bad -> undefined behavior is the only sane thing to do in the standard.

                I completely agree!

                I guess it's a language design decision. Calling a method without an instance is what static methods are for. If nulls were explicitly allowed in non-static methods you would have if(!this) return; or similar on top of virtually every method out there. That would be horrible.

                Granted, but I personally see no reason to forcefully impose that restriction. Nonetheless, as you said, it's probably just a design decision.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • Chris KawaC Online
                  Chris KawaC Online
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by Chris Kawa
                  #8

                  @kshegunov said:

                  but I personally see no reason to forcefully impose that restriction

                  Agreed, there's certainly no technical reason, but I, for one, am glad that c++ has this restriction. I really wouldn't want to review code like this:

                  static_cast<SomeClass*>(nullptr)->someMethod(42);
                  

                  As a sidenote to this topic, there are a couple of proposals for C++17 for something called "unified call syntax". Depending on the final wording of the standard it's possible that soon we'll be able to write the above as

                  someMethod(static_cast<SomeClass*>(nullptr), 42);
                  

                  which looks a bit less surprising, but personally, I'm not a big fan of this. I think more syntax possibilities brings even more complexity and gotchas to the language, which I don't think C++ is in deficit of.

                  ? kshegunovK 2 Replies Last reply
                  0
                  • Chris KawaC Chris Kawa

                    @kshegunov said:

                    but I personally see no reason to forcefully impose that restriction

                    Agreed, there's certainly no technical reason, but I, for one, am glad that c++ has this restriction. I really wouldn't want to review code like this:

                    static_cast<SomeClass*>(nullptr)->someMethod(42);
                    

                    As a sidenote to this topic, there are a couple of proposals for C++17 for something called "unified call syntax". Depending on the final wording of the standard it's possible that soon we'll be able to write the above as

                    someMethod(static_cast<SomeClass*>(nullptr), 42);
                    

                    which looks a bit less surprising, but personally, I'm not a big fan of this. I think more syntax possibilities brings even more complexity and gotchas to the language, which I don't think C++ is in deficit of.

                    ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by
                    #9

                    @Chris-Kawa Hooray! More new C++ syntax... :-/

                    1 Reply Last reply
                    1
                    • Chris KawaC Chris Kawa

                      @kshegunov said:

                      but I personally see no reason to forcefully impose that restriction

                      Agreed, there's certainly no technical reason, but I, for one, am glad that c++ has this restriction. I really wouldn't want to review code like this:

                      static_cast<SomeClass*>(nullptr)->someMethod(42);
                      

                      As a sidenote to this topic, there are a couple of proposals for C++17 for something called "unified call syntax". Depending on the final wording of the standard it's possible that soon we'll be able to write the above as

                      someMethod(static_cast<SomeClass*>(nullptr), 42);
                      

                      which looks a bit less surprising, but personally, I'm not a big fan of this. I think more syntax possibilities brings even more complexity and gotchas to the language, which I don't think C++ is in deficit of.

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

                      @Chris-Kawa

                      I'm not a big fan of this

                      Neither would any person with any sense ... I can live with C++11 and its somewhat unnecessary additions (not all, but I was perfectly fine writing functors instead of lambdas, and I wouldn't even start on the auto 'cause it'd would end up as a very long and needlessly opinionated post). But that ... that is ... meh!!

                      I think more syntax possibilities brings even more complexity and gotchas to the language, which I don't think C++ is in deficit of.

                      ... to put it really, really mildly. C++ is already the monster-elephant of complexity ... putting more, in practice, only makes it less usable ...

                      Read and abide by the Qt Code of Conduct

                      1 Reply Last reply
                      0
                      • Chris KawaC Online
                        Chris KawaC Online
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @kshegunov said:

                        Neither would any person with any sense ...

                        haha, apparently one of the ones that do would be the creator of the language ;) A bit of background for the unified call proposal. Herb Sutter of Microsoft is even more radical with this. His proposal is that any of x->f(a,b), f(x,a,b), f(a,x,b), f(a,b,x) is the same, which is madness if you ask me.

                        kshegunovK 1 Reply Last reply
                        0
                        • Chris KawaC Chris Kawa

                          @kshegunov said:

                          Neither would any person with any sense ...

                          haha, apparently one of the ones that do would be the creator of the language ;) A bit of background for the unified call proposal. Herb Sutter of Microsoft is even more radical with this. His proposal is that any of x->f(a,b), f(x,a,b), f(a,x,b), f(a,b,x) is the same, which is madness if you ask me.

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

                          @Chris-Kawa

                          haha, apparently one of the ones that do would be the creator of the language

                          He may be, but he's wrong! :)
                          Thanks for the link though, it's certainly interesting.

                          On a related note, I still don't see how you distinguish these 2 prototypes:

                          void A::f(int);
                          void f(const A &, int);
                          
                          A a;
                          f(a, 3); //< So, what do we call here or we are to resort to the help of a fortuneteller?
                          

                          And to pile up no one is preventing anyone from actually invoking "methods" of such structures by friend functions. Hell, before having C++ that's how it was done in the first place! :)

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          0
                          • Chris KawaC Online
                            Chris KawaC Online
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @kshegunov said:

                            I still don't see how you distinguish these 2 prototypes

                            I think that's largely the difference between different proposals right now. We'll have to wait and see which (if any) gets voted in. One of them is that "the closest match" is chosen i.e. for f(a, 3) a free standing function would be preferred, and, if there isn't one, members of A are checked for match. If I understand correctly the thing that Stroustrup prefers is that these would mean the same, i.e. they would be treated as overloads and abide to the same rules (ambiguous call error in this case), but apparently (fortunately) that would break too much code out there.
                            I really don't like all this, but to be entirely fair, members are really no different from free functions and "this" injection is just a syntax sugar. On some level it would make sense... i guess... ugh, no, I still don't like it :P

                            kshegunovK 1 Reply Last reply
                            0
                            • Chris KawaC Chris Kawa

                              @kshegunov said:

                              I still don't see how you distinguish these 2 prototypes

                              I think that's largely the difference between different proposals right now. We'll have to wait and see which (if any) gets voted in. One of them is that "the closest match" is chosen i.e. for f(a, 3) a free standing function would be preferred, and, if there isn't one, members of A are checked for match. If I understand correctly the thing that Stroustrup prefers is that these would mean the same, i.e. they would be treated as overloads and abide to the same rules (ambiguous call error in this case), but apparently (fortunately) that would break too much code out there.
                              I really don't like all this, but to be entirely fair, members are really no different from free functions and "this" injection is just a syntax sugar. On some level it would make sense... i guess... ugh, no, I still don't like it :P

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

                              @Chris-Kawa

                              One of them is that "the closest match" is chosen i.e. for f(a, 3) a free standing function would be preferred, and, if there isn't one, members of A are checked for match.

                              Which would basically mean to pile on the ever so problematic partial inference of types, and as you said add yet another level of complexity for the programmer. One of the big critiques about C++ is it's implicit conversion (I suppose inherited through C) and this "unified call" syntax just makes that ever more implicit.

                              but apparently (fortunately) that would break too much code out there.

                              Thank god for small favors ... :)

                              I really don't like all this, but to be entirely fair, members are really no different from free functions and "this" injection is just a syntax sugar.

                              Sure, however the purpose of having members is to have the "this" injection. Otherwise we'd all write functions that operate on POD structures ... oh, well, we used to do it so why would be so reluctant to do it again ...?

                              On some level it would make sense... i guess... ugh, no, I still don't like it :P

                              I'm with you, Chris, sadly I don't get to vote!

                              Read and abide by the Qt Code of Conduct

                              1 Reply Last reply
                              0

                              • Login

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