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. Is it possible to prevent `delete` on a `const *`?
QtWS25 Last Chance

Is it possible to prevent `delete` on a `const *`?

Scheduled Pinned Locked Moved Solved C++ Gurus
17 Posts 7 Posters 2.1k Views
  • 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.
  • J Offline
    J Offline
    JonB
    wrote on 8 Jun 2024, 09:09 last edited by JonB 6 Aug 2024, 09:43
    #1

    Wondering idly whether C++ allows me to prevent going delete on a const Something *?

    // list of pointers to things, where the things pointed to must not be changed
    QList<const Something *> somethings;
    somethings[...] = new Something;
    
    // get a pointer to one thing, where the thing pointed to cannot be changed
    const Something *something = somethings.at(somewhere);
    

    All good so far. Trying to go something->member = somesuch gives me a compiler error assignment of member ‘Something::member’ in read-only object.

    But delete something is accepted. I'd like to prevent that. It does not "change" what something points to, so far as compiler is concerned. OTOH it makes *something quite "invalid", which is a kind of change.... And if Debug it may even write into the freed pointed to area for internal reasons, which again is a kind of change.

    I tried

    const Something *const something = somethings.at(somewhere);
    

    This makes the something pointer be read-only itself. If I go

    delete something;
    something = nullptr;
    

    it errors on the attempt to go something = nullptr. But, sadly for me, not on the delete something statement. If delete pointer took a reference and also did a pointer = nullptr itself the compiler would complain. But it does not. So the extra *const here does not do what I would like.

    Anyone know a way to achieve this in C++?

    J 1 Reply Last reply 8 Jun 2024, 19:22
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 8 Jun 2024, 15:12 last edited by
      #2

      Hi,

      I think you can achieve that by declaring the delete operator of your class private or protected if you want to allow for proper subclassing.
      You can then add a dedicated method to allow the destruction of these object in a more controlled manner.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      J 1 Reply Last reply 8 Jun 2024, 19:40
      5
      • J JonB
        8 Jun 2024, 09:09

        Wondering idly whether C++ allows me to prevent going delete on a const Something *?

        // list of pointers to things, where the things pointed to must not be changed
        QList<const Something *> somethings;
        somethings[...] = new Something;
        
        // get a pointer to one thing, where the thing pointed to cannot be changed
        const Something *something = somethings.at(somewhere);
        

        All good so far. Trying to go something->member = somesuch gives me a compiler error assignment of member ‘Something::member’ in read-only object.

        But delete something is accepted. I'd like to prevent that. It does not "change" what something points to, so far as compiler is concerned. OTOH it makes *something quite "invalid", which is a kind of change.... And if Debug it may even write into the freed pointed to area for internal reasons, which again is a kind of change.

        I tried

        const Something *const something = somethings.at(somewhere);
        

        This makes the something pointer be read-only itself. If I go

        delete something;
        something = nullptr;
        

        it errors on the attempt to go something = nullptr. But, sadly for me, not on the delete something statement. If delete pointer took a reference and also did a pointer = nullptr itself the compiler would complain. But it does not. So the extra *const here does not do what I would like.

        Anyone know a way to achieve this in C++?

        J Offline
        J Offline
        JoeCFD
        wrote on 8 Jun 2024, 19:22 last edited by JoeCFD 6 Oct 2024, 12:40
        #3

        @JonB
        const SomeClass *const something has two meanings:

        1. can call only const funcs
        2. its address can not be changed.

        delete something; does not change its address. Instead deletes the contents something points to. Still a dangled pointer;
        something = nullptr; changes its address, not allowed.

        I guess you may try a Wrapper class

        class WrapperPointer {
        public:
            WrapperPointer(int* ptr) : ptr(ptr) {}
        
            ~WrapperPointer() {
                // does nothing
            }
        
            int* get() const { /* can be used to clear pointer as well */
                return ptr;
            }
        
        private:
            int* ptr{};
        };
        
        S 1 Reply Last reply 10 Jun 2024, 08:41
        1
        • S SGaist
          8 Jun 2024, 15:12

          Hi,

          I think you can achieve that by declaring the delete operator of your class private or protected if you want to allow for proper subclassing.
          You can then add a dedicated method to allow the destruction of these object in a more controlled manner.

          J Offline
          J Offline
          JonB
          wrote on 8 Jun 2024, 19:40 last edited by
          #4

          @SGaist said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

          declaring the delete operator of your class private or protected

          Ohh, I didn't even know delete was an operator and you can override it.

          @JoeCFD
          Yes, you are right about * const ptr, that just affects its value. I wish delete ptr set ptr to nullptr, then I would not be allowed to delete *const ptr which would suit me :)

          1 Reply Last reply
          0
          • J Offline
            J Offline
            JonB
            wrote on 8 Jun 2024, 19:55 last edited by JonB 6 Aug 2024, 19:59
            #5

            There is still one concept I don't uderstand. I got side-tracked with the second const, forget that.

            const Foo *foo = somefunc();
            
            • I can't go foo->something = somewhat because error const/read-only, perfect.

            • But I can go delete foo (given a standard delete). Why? delete frees the memory used by the object. That's just as destructive as assigning into it. If I need a non-const pointer for write access why don't I need that to delete too?

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 8 Jun 2024, 21:22 last edited by Chris Kawa 6 Aug 2024, 21:34
              #6

              You could look at constructors and destructors as "special" functions that follow slightly different set of rules than other member functions. For example did you know that delete operator is the only static member function in C++ that is called polymorphically?

              You could have a philosophical take on it by saying that accessing a regular mutating member is different operation than deallocating an object as a whole, but then there's the issue of mutating destructors. You could give it a pragmatic explanation that disallowing destruction through pointer to const could lead to a situation where there's no way to delete an object without a const_cast if all you have are just pointers to const. That would be fugly. You could take a C style explanation that it just deals with memory and not access, but then there are destructors...

              It is what it is is what I'm trying to say. One of the many quirks of a complicated language :)

              1 Reply Last reply
              5
              • J JoeCFD
                8 Jun 2024, 19:22

                @JonB
                const SomeClass *const something has two meanings:

                1. can call only const funcs
                2. its address can not be changed.

                delete something; does not change its address. Instead deletes the contents something points to. Still a dangled pointer;
                something = nullptr; changes its address, not allowed.

                I guess you may try a Wrapper class

                class WrapperPointer {
                public:
                    WrapperPointer(int* ptr) : ptr(ptr) {}
                
                    ~WrapperPointer() {
                        // does nothing
                    }
                
                    int* get() const { /* can be used to clear pointer as well */
                        return ptr;
                    }
                
                private:
                    int* ptr{};
                };
                
                S Offline
                S Offline
                SimonSchroeder
                wrote on 10 Jun 2024, 08:41 last edited by
                #7

                @JoeCFD said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                1. can call only const funcs

                delete does not only delete the contents something points to. It also calls the destructor of the underlying object. So, there is an inconsistency that I can call the destructor on a const object (which I never noticed in my long C++ career).

                Best advice is to not use plain owning pointers in C++. But, that would still leave you with the convention to use raw pointers as non-owning pointers with the technical possibility that someone calls delete on them. Making the delete operator private works to suppress this, but is also really intrusive to be of general use.

                J 1 Reply Last reply 10 Jun 2024, 08:47
                1
                • S SimonSchroeder
                  10 Jun 2024, 08:41

                  @JoeCFD said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                  1. can call only const funcs

                  delete does not only delete the contents something points to. It also calls the destructor of the underlying object. So, there is an inconsistency that I can call the destructor on a const object (which I never noticed in my long C++ career).

                  Best advice is to not use plain owning pointers in C++. But, that would still leave you with the convention to use raw pointers as non-owning pointers with the technical possibility that someone calls delete on them. Making the delete operator private works to suppress this, but is also really intrusive to be of general use.

                  J Offline
                  J Offline
                  JonB
                  wrote on 10 Jun 2024, 08:47 last edited by JonB 6 Oct 2024, 13:12
                  #8

                  @SimonSchroeder said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                  It also calls the destructor of the underlying object. So, there is an inconsistency that I can call the destructor on a const object (which I never noticed in my long C++ career).

                  Exactly! I am "surprised" that you have never "noticed" this, as I most certainly have, and is precisely why I am so shocked it is allowed! :) I am finding this whole "you cannot change the object via const * but feel free to completely clobber it by deleting" very odd!

                  jsulmJ J.HilkJ 2 Replies Last reply 11 Jun 2024, 05:23
                  0
                  • J JonB has marked this topic as solved on 10 Jun 2024, 16:42
                  • J JonB
                    10 Jun 2024, 08:47

                    @SimonSchroeder said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                    It also calls the destructor of the underlying object. So, there is an inconsistency that I can call the destructor on a const object (which I never noticed in my long C++ career).

                    Exactly! I am "surprised" that you have never "noticed" this, as I most certainly have, and is precisely why I am so shocked it is allowed! :) I am finding this whole "you cannot change the object via const * but feel free to completely clobber it by deleting" very odd!

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on 11 Jun 2024, 05:23 last edited by
                    #9

                    @JonB said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                    I am finding this whole "you cannot change the object via const * but feel free to completely clobber it by deleting" very odd!

                    Else, you would not be able to free the memory

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • J JonB
                      10 Jun 2024, 08:47

                      @SimonSchroeder said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                      It also calls the destructor of the underlying object. So, there is an inconsistency that I can call the destructor on a const object (which I never noticed in my long C++ career).

                      Exactly! I am "surprised" that you have never "noticed" this, as I most certainly have, and is precisely why I am so shocked it is allowed! :) I am finding this whole "you cannot change the object via const * but feel free to completely clobber it by deleting" very odd!

                      J.HilkJ Online
                      J.HilkJ Online
                      J.Hilk
                      Moderators
                      wrote on 11 Jun 2024, 07:06 last edited by
                      #10

                      @JonB said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                      I am finding this whole "you cannot change the object via const * but feel free to completely clobber it by deleting" very odd!

                      freeing an objects memory is very much different from changing its internal state. const only prohibits the later


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      J 1 Reply Last reply 11 Jun 2024, 08:38
                      1
                      • J.HilkJ J.Hilk
                        11 Jun 2024, 07:06

                        @JonB said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                        I am finding this whole "you cannot change the object via const * but feel free to completely clobber it by deleting" very odd!

                        freeing an objects memory is very much different from changing its internal state. const only prohibits the later

                        J Offline
                        J Offline
                        JonB
                        wrote on 11 Jun 2024, 08:38 last edited by
                        #11

                        @J-Hilk said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                        freeing an objects memory is very much different from changing its internal state. const only prohibits the later

                        Well it may be "different" but it is equally "destructive". And ends up "changing its internal state" as a consequence. Hence the discussion. I now get that "const only prohibits the later", and that's life, but I still find it "odd".

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          SimonSchroeder
                          wrote on 12 Jun 2024, 06:22 last edited by
                          #12

                          I was just thinking about this: Is it possible to overload the delete operator with a const and non-const version?

                          J 1 Reply Last reply 12 Jun 2024, 08:35
                          0
                          • S SimonSchroeder
                            12 Jun 2024, 06:22

                            I was just thinking about this: Is it possible to overload the delete operator with a const and non-const version?

                            J Offline
                            J Offline
                            JonB
                            wrote on 12 Jun 2024, 08:35 last edited by JonB 6 Dec 2024, 08:36
                            #13

                            @SimonSchroeder
                            So for my case that would do what, presumably runtime error? I was looking for a compile-time error on attempting to delete a const pointer (like I would get on attempting to write to a member/call a non-const member method).

                            J.HilkJ S 2 Replies Last reply 12 Jun 2024, 09:40
                            0
                            • J JonB
                              12 Jun 2024, 08:35

                              @SimonSchroeder
                              So for my case that would do what, presumably runtime error? I was looking for a compile-time error on attempting to delete a const pointer (like I would get on attempting to write to a member/call a non-const member method).

                              J.HilkJ Online
                              J.HilkJ Online
                              J.Hilk
                              Moderators
                              wrote on 12 Jun 2024, 09:40 last edited by
                              #14

                              @JonB make yourself a delete macro, that calls delete and setzt the pointer to nullptr :D


                              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                              Q: What's that?
                              A: It's blue light.
                              Q: What does it do?
                              A: It turns blue.

                              J 1 Reply Last reply 12 Jun 2024, 10:23
                              0
                              • J.HilkJ J.Hilk
                                12 Jun 2024, 09:40

                                @JonB make yourself a delete macro, that calls delete and setzt the pointer to nullptr :D

                                J Offline
                                J Offline
                                JonB
                                wrote on 12 Jun 2024, 10:23 last edited by
                                #15

                                @J-Hilk My badly-behaved fellow programmers can/will call delete directly, and I want them to fall over at compile time as per trying to write into the const pointer!

                                1 Reply Last reply
                                0
                                • J JonB
                                  12 Jun 2024, 08:35

                                  @SimonSchroeder
                                  So for my case that would do what, presumably runtime error? I was looking for a compile-time error on attempting to delete a const pointer (like I would get on attempting to write to a member/call a non-const member method).

                                  S Offline
                                  S Offline
                                  SimonSchroeder
                                  wrote on 13 Jun 2024, 06:30 last edited by
                                  #16

                                  @JonB said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                                  So for my case that would do what, presumably runtime error?

                                  If you can distinguish that, you could make the const-version private and the non-const public. So, you can still normally delete objects when you are allowed to (with a pointer to non-const). But I'm not sure if this distinction is possible.

                                  C 1 Reply Last reply 13 Jun 2024, 06:48
                                  0
                                  • S SimonSchroeder
                                    13 Jun 2024, 06:30

                                    @JonB said in Is it possible to prevent &#x60;delete&#x60; on a &#x60;const *&#x60;?:

                                    So for my case that would do what, presumably runtime error?

                                    If you can distinguish that, you could make the const-version private and the non-const public. So, you can still normally delete objects when you are allowed to (with a pointer to non-const). But I'm not sure if this distinction is possible.

                                    C Offline
                                    C Offline
                                    Chris Kawa
                                    Lifetime Qt Champion
                                    wrote on 13 Jun 2024, 06:48 last edited by Chris Kawa
                                    #17

                                    @SimonSchroeder said:

                                    But I'm not sure if this distinction is possible

                                    It's not. The delete operator can't be cv qualified.

                                    Here's a fun quirk:

                                    struct Foo {
                                        void itIsFine() const { delete this; }
                                        ~Foo() {  bar = 42; }
                                        int bar = 0;
                                    };
                                    
                                    const Foo* foo = new Foo();
                                    foo->itIsFine();
                                    

                                    so not only can you delete an object through a pointer to const, but a const function can mutate the object without mutable or const_cast by deleting the object it is being called on;)

                                    1 Reply Last reply
                                    0

                                    1/17

                                    8 Jun 2024, 09:09

                                    • Login

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