Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. C++ is love

C++ is love

Scheduled Pinned Locked Moved The Lounge
csharpc++
86 Posts 24 Posters 11 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.
  • U User 13269747

    Not much improvement, just a few observations: 1. Identifiers starting with underscores are reserved. If you use them then your program is non-conforming for no good reason. 2. The comparison against capacity in both the static and dynamic classes result in never being able to use the last byte of the pool: The "used()>=capacity" should be "used()>capacity". To test it instantiate a pool of 10 bytes and allocate 6. The (capacity() - used()) is then 4, but a further allocation of 4 fails. A further allocation of 3, on the other hand, succeeds and (capacity() - used()) is then 1. 3. The static pool could benefit from a #warning directive when C is too large. Right now a 8MB C when instantiating it (1024 * 1024 * 8) would almost certainly overflow the stack, and 8MB is not a lot of memory.

    honey the codewitchH Offline
    honey the codewitchH Offline
    honey the codewitch
    wrote on last edited by
    #65

    1. I thought they were only reserved for globals. I stand corrected. 2. Good catch. 3. The static pool can and often is declared as a global, making it heap/not stack, which is where it's primarily designed to go. DynamicMemoryPool is probably a better choice if you need a locally scoped pool because it always allocates from the heap. Thanks!

    Real programmers use butterflies

    1 Reply Last reply
    0
    • D den2k88

      W∴ Balboos, GHB wrote:

      I'd presume it used the stack for memory.

      Yep, exactly. I had the habit of making objects "stackable" whenever possible, for example strings had fixed size straight into the struct, so the whole object was a single contiguous dataspace easily allocatable in the stack and passed around with a memcpy. Of course it isn't alwasy the best option but I like it when it is.

      GCS d--(d+) s-/++ a C++++ U+++ P- L+@ E-- W++ N+ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t+ 5? X R+++ tv-- b+(+++) DI+++ D++ G e++ h--- r+++ y+++*      Weapons extension: ma- k++ F+2 X

      K Offline
      K Offline
      Kirk 10389821
      wrote on last edited by
      #66

      I had a programmer who was notorious for declaring char somestr[256]; and RETURNING somestr out of the function to be used by others. "But it runs fine in the debugger" was his last refrain... LOL

      honey the codewitchH 1 Reply Last reply
      0
      • honey the codewitchH honey the codewitch

        It's not. It's the truth. I'm married to a communist, but that doesn't make me one.

        Real programmers use butterflies

        S Offline
        S Offline
        Slacker007
        wrote on last edited by
        #67

        honey the codewitch wrote:

        I'm married to a communist

        I shudder at the thought.

        honey the codewitchH 1 Reply Last reply
        0
        • S Slacker007

          honey the codewitch wrote:

          I'm married to a communist

          I shudder at the thought.

          honey the codewitchH Offline
          honey the codewitchH Offline
          honey the codewitch
          wrote on last edited by
          #68

          He's nice. He likes to share, and has a fondness for bureaucracy which I find in explicable. I'm pretty much the antithesis to that so we balance. Still, to each their own.

          Real programmers use butterflies

          1 Reply Last reply
          0
          • K Kirk 10389821

            I had a programmer who was notorious for declaring char somestr[256]; and RETURNING somestr out of the function to be used by others. "But it runs fine in the debugger" was his last refrain... LOL

            honey the codewitchH Offline
            honey the codewitchH Offline
            honey the codewitch
            wrote on last edited by
            #69

            declaring it on the stack? ouch. I only return char*s from functions if I'm using some kind of memory management scheme that allows for it. Unless you implement one C and C++ ... doesn't. I can't judge people too badly though, considering I just got schooled on using leading underscores in my local member names (a habit I picked up from C#) But still, you should understand scoping if you're going to get paid to code in the thing.

            Real programmers use butterflies

            J 1 Reply Last reply
            0
            • W W Balboos GHB

              (fill in clever retort of your choice)                  Ravings en masse^

              "The difference between genius and stupidity is that genius has its limits." - Albert Einstein

              "If you are searching for perfection in others, then you seek disappointment. If you seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010

              J Offline
              J Offline
              jsc42
              wrote on last edited by
              #70

              [

              W∴ Balboos, GHB wrote:

              (fill in clever retort of your choice)

              Amazon.co.uk : glass retort](https://www.amazon.co.uk/s?k=glass+retort&hvadid=80401819685055&hvbmt=be&hvdev=c&hvqmt=e&tag=mh0a9-21&ref=pd_sl_7xksutbpbn_e)[^]

              D 1 Reply Last reply
              0
              • D Daniel Pfeffer

                Only use code that runs as expected on the [DeathStation 9000](https://enacademic.com/dic.nsf/enwiki/2748465)!

                Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

                K Offline
                K Offline
                k5054
                wrote on last edited by
                #71

                Thank you. I've been trying to remember the name of that system for ages. I had been meaning to use it in QA, but it's probably too arcane for 99% of those who post questions there.

                Keep Calm and Carry On

                1 Reply Last reply
                0
                • J jsc42

                  [

                  W∴ Balboos, GHB wrote:

                  (fill in clever retort of your choice)

                  Amazon.co.uk : glass retort](https://www.amazon.co.uk/s?k=glass+retort&hvadid=80401819685055&hvbmt=be&hvdev=c&hvqmt=e&tag=mh0a9-21&ref=pd_sl_7xksutbpbn_e)[^]

                  D Offline
                  D Offline
                  Daniel Pfeffer
                  wrote on last edited by
                  #72

                  That retort is a better retort than I had thought of retorting.

                  Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

                  1 Reply Last reply
                  0
                  • honey the codewitchH honey the codewitch

                    go ahead. my C++ is rusty so I'm sure there's stuff to be improved.

                    Real programmers use butterflies

                    M Offline
                    M Offline
                    Mladen Jankovic
                    wrote on last edited by
                    #73
                    1. ditch the using namespace std; in header files, 2) you don't have virtual destructor for `MemoryPool` and 3) if you're using C++17 you might want to check memory_resource class/header
                    honey the codewitchH 1 Reply Last reply
                    0
                    • M Mladen Jankovic
                      1. ditch the using namespace std; in header files, 2) you don't have virtual destructor for `MemoryPool` and 3) if you're using C++17 you might want to check memory_resource class/header
                      honey the codewitchH Offline
                      honey the codewitchH Offline
                      honey the codewitch
                      wrote on last edited by
                      #74
                      1. forgive me for asking, but why? edit: whoops that was an error. if anything it was supposed to be inside the file's namespace 2) MemoryPool is an interface - a pure abstract base. what is the purpose of a virtual destructor in such a contract as it holds no resources? - never mind. I was thinking about the call chain backwards. derived classes need to have their destructor called if the base goes out of scope. i forgot. I'm rusty. 3) I'm targeting C++11 for now because reasons having to do with the platforms this is primarily for.

                      Real programmers use butterflies

                      M 2 Replies Last reply
                      0
                      • honey the codewitchH honey the codewitch
                        1. forgive me for asking, but why? edit: whoops that was an error. if anything it was supposed to be inside the file's namespace 2) MemoryPool is an interface - a pure abstract base. what is the purpose of a virtual destructor in such a contract as it holds no resources? - never mind. I was thinking about the call chain backwards. derived classes need to have their destructor called if the base goes out of scope. i forgot. I'm rusty. 3) I'm targeting C++11 for now because reasons having to do with the platforms this is primarily for.

                        Real programmers use butterflies

                        M Offline
                        M Offline
                        Mladen Jankovic
                        wrote on last edited by
                        #75
                        1. you don't want to introduce bunch of names from std into client's scope, can cause all kind of nasty problems for users. C++ name lookup is complex as it is. 2) if I got a pointer to MemoryPool and tried to delete the referenced object, I would invoke undefined behavior, even thought virtual methods are strongly suggesting me that I should be able to do it Some more points, since you said C++ is love: 4) virtual void* alloc(const size_t size)=0; - const is needless 5) if(!TCapacity) will give you a warning (on /W4 maybe) if TCapacity is 0, but 6) the bigger problem is `uint8_t m_heap[TCapacity]`, since zero-sized arrays is not standard C++ So I would either go with static_assert and ensure that 0 is not valid value or make specialization for that cas.
                        honey the codewitchH 1 Reply Last reply
                        0
                        • honey the codewitchH honey the codewitch
                          1. forgive me for asking, but why? edit: whoops that was an error. if anything it was supposed to be inside the file's namespace 2) MemoryPool is an interface - a pure abstract base. what is the purpose of a virtual destructor in such a contract as it holds no resources? - never mind. I was thinking about the call chain backwards. derived classes need to have their destructor called if the base goes out of scope. i forgot. I'm rusty. 3) I'm targeting C++11 for now because reasons having to do with the platforms this is primarily for.

                          Real programmers use butterflies

                          M Offline
                          M Offline
                          Mladen Jankovic
                          wrote on last edited by
                          #76

                          And some more: 7) You invoke undefined behavior in `~DynamicMemoryPool` by calling delete operator instead of delete[] 8) i guess capacity, used, next should be const-qualified C++ IS LOVE :)

                          honey the codewitchH 1 Reply Last reply
                          0
                          • U User 13269747

                            Not much improvement, just a few observations: 1. Identifiers starting with underscores are reserved. If you use them then your program is non-conforming for no good reason. 2. The comparison against capacity in both the static and dynamic classes result in never being able to use the last byte of the pool: The "used()>=capacity" should be "used()>capacity". To test it instantiate a pool of 10 bytes and allocate 6. The (capacity() - used()) is then 4, but a further allocation of 4 fails. A further allocation of 3, on the other hand, succeeds and (capacity() - used()) is then 1. 3. The static pool could benefit from a #warning directive when C is too large. Right now a 8MB C when instantiating it (1024 * 1024 * 8) would almost certainly overflow the stack, and 8MB is not a lot of memory.

                            M Offline
                            M Offline
                            Mladen Jankovic
                            wrote on last edited by
                            #77
                            1. gotta love C++, since rules for reserved names are even more complex that, depending on scope, case, number of underscores... 3) or static_assert to keep it in the family language.
                            1 Reply Last reply
                            0
                            • M Mladen Jankovic
                              1. you don't want to introduce bunch of names from std into client's scope, can cause all kind of nasty problems for users. C++ name lookup is complex as it is. 2) if I got a pointer to MemoryPool and tried to delete the referenced object, I would invoke undefined behavior, even thought virtual methods are strongly suggesting me that I should be able to do it Some more points, since you said C++ is love: 4) virtual void* alloc(const size_t size)=0; - const is needless 5) if(!TCapacity) will give you a warning (on /W4 maybe) if TCapacity is 0, but 6) the bigger problem is `uint8_t m_heap[TCapacity]`, since zero-sized arrays is not standard C++ So I would either go with static_assert and ensure that 0 is not valid value or make specialization for that cas.
                              honey the codewitchH Offline
                              honey the codewitchH Offline
                              honey the codewitch
                              wrote on last edited by
                              #78

                              1&2 - see my edited post 4, i use const descriptively, even if it doesn't do anything, unless there's a reason I shouldn't 5, yeah that's a nasty habit of mine 6 I introduced a static_assert to fix that in my later code.

                              Real programmers use butterflies

                              M 1 Reply Last reply
                              0
                              • M Mladen Jankovic

                                And some more: 7) You invoke undefined behavior in `~DynamicMemoryPool` by calling delete operator instead of delete[] 8) i guess capacity, used, next should be const-qualified C++ IS LOVE :)

                                honey the codewitchH Offline
                                honey the codewitchH Offline
                                honey the codewitch
                                wrote on last edited by
                                #79

                                whoops, and yeah your probably right. i love const and i hate const because i always forget it.

                                Real programmers use butterflies

                                M 1 Reply Last reply
                                0
                                • honey the codewitchH honey the codewitch

                                  whoops, and yeah your probably right. i love const and i hate const because i always forget it.

                                  Real programmers use butterflies

                                  M Offline
                                  M Offline
                                  Mladen Jankovic
                                  wrote on last edited by
                                  #80
                                  1. you want to disable copy and move operations (constructor and assign operation) on StaticMemoryPool and copy operations on DynamicMemoryPool 10) ~StaticMemoryPool() {} don't provide user-defined special members functions if they are not really necessary and if you do have to define them because language rules deleted them, use = default to retain possible triviality of these operations General rule is if you need to provide a single user-defined SMF, you need to provide them all. It was called rule-of-three, now it's known as rule-of-five. Think about using clang-format and clang-tidy (they integrate well with VS these days).
                                  honey the codewitchH 1 Reply Last reply
                                  0
                                  • M Mladen Jankovic
                                    1. you want to disable copy and move operations (constructor and assign operation) on StaticMemoryPool and copy operations on DynamicMemoryPool 10) ~StaticMemoryPool() {} don't provide user-defined special members functions if they are not really necessary and if you do have to define them because language rules deleted them, use = default to retain possible triviality of these operations General rule is if you need to provide a single user-defined SMF, you need to provide them all. It was called rule-of-three, now it's known as rule-of-five. Think about using clang-format and clang-tidy (they integrate well with VS these days).
                                    honey the codewitchH Offline
                                    honey the codewitchH Offline
                                    honey the codewitch
                                    wrote on last edited by
                                    #81

                                    Okay I am aware of the rule of five but I don't actually want copy and move operations to work, consequently, no move and copy operations. Currently if I try to do those things, I'm pretty sure it doesn't compile. What's wrong with that?

                                    Real programmers use butterflies

                                    M 1 Reply Last reply
                                    0
                                    • honey the codewitchH honey the codewitch

                                      Okay I am aware of the rule of five but I don't actually want copy and move operations to work, consequently, no move and copy operations. Currently if I try to do those things, I'm pretty sure it doesn't compile. What's wrong with that?

                                      Real programmers use butterflies

                                      M Offline
                                      M Offline
                                      Mladen Jankovic
                                      wrote on last edited by
                                      #82

                                      Are you sure it does not compile? [Copy and move operations does not produce error](https://godbolt.org/z/8vadqM) Rules for which SMFs get deleted by compiler and which remain defaulted are a bit complex, so that's why it's better to be explicit about it and = delete those that you don't want and = default those that you want to keep. The second point is to always prefer = default over {} since you retain triviality which is actual concept. Trivial type are easier to handle, subject to more optimizations and can be used in wider range of situations. It something that you probably don't need for arena allocator, so in this case it would be about habit and consistency.

                                      honey the codewitchH 1 Reply Last reply
                                      0
                                      • M Mladen Jankovic

                                        Are you sure it does not compile? [Copy and move operations does not produce error](https://godbolt.org/z/8vadqM) Rules for which SMFs get deleted by compiler and which remain defaulted are a bit complex, so that's why it's better to be explicit about it and = delete those that you don't want and = default those that you want to keep. The second point is to always prefer = default over {} since you retain triviality which is actual concept. Trivial type are easier to handle, subject to more optimizations and can be used in wider range of situations. It something that you probably don't need for arena allocator, so in this case it would be about habit and consistency.

                                        honey the codewitchH Offline
                                        honey the codewitchH Offline
                                        honey the codewitch
                                        wrote on last edited by
                                        #83

                                        Now that you mention it I'm not sure. I guess I should be explicit.

                                        Real programmers use butterflies

                                        1 Reply Last reply
                                        0
                                        • honey the codewitchH honey the codewitch

                                          1&2 - see my edited post 4, i use const descriptively, even if it doesn't do anything, unless there's a reason I shouldn't 5, yeah that's a nasty habit of mine 6 I introduced a static_assert to fix that in my later code.

                                          Real programmers use butterflies

                                          M Offline
                                          M Offline
                                          Mladen Jankovic
                                          wrote on last edited by
                                          #84

                                          honey the codewitch wrote:

                                          4, i use const descriptively, even if it doesn't do anything, unless there's a reason I shouldn't

                                          To whom this description is directed? Users of the interface don't not care about it. Implementer of the interface is [free to leave it out when override the function](https://godbolt.org/z/as7Mzv), since compiler ignores const when doing overload resolution. It is just implementation thing leaking into syntax of function signature, but not really affecting it. You can keep it class implementing abstract function to prevent changes to the parameter in the function's body, but in the base class it just confusing.

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups