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. Other Discussions
  3. The Weird and The Wonderful
  4. Lets' change things up; how about the inept and stupid

Lets' change things up; how about the inept and stupid

Scheduled Pinned Locked Moved The Weird and The Wonderful
linuxhelp
18 Posts 10 Posters 27 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.
  • G Gary R Wheeler

    I've been debugging my first Windows shell extension, and just realized the problem with the following:

    _TCHAR *buffer = new _TCHAR(buffer_size);

    No compiler warnings or errors either.

    Software Zen: delete this;

    M Offline
    M Offline
    Member 9167057
    wrote on last edited by
    #4

    C++ tried it's best to be compatible with C at the beginning, including it's idiosyncrasies. What's the point in the compiler guessing what the programmer's intention might be?

    J 1 Reply Last reply
    0
    • Greg UtasG Greg Utas

      :laugh: C++ is too often like that. You write something that compiles, but it doesn't do what you think. Recently I was answering a question where a newbie had written

      if(a && b < n)

      believing that it meant

      if((a < n) && (b < n))

      S Offline
      S Offline
      Stefan_Lang
      wrote on last edited by
      #5

      Yeah, I've seen that. Wasn't that the same posting which tried to express a pair using the syntax (a,b)? :doh:

      GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

      Greg UtasG 1 Reply Last reply
      0
      • G Gary R Wheeler

        I've been debugging my first Windows shell extension, and just realized the problem with the following:

        _TCHAR *buffer = new _TCHAR(buffer_size);

        No compiler warnings or errors either.

        Software Zen: delete this;

        S Offline
        S Offline
        Stefan_Lang
        wrote on last edited by
        #6

        That's one of the problems that don't fit modern coding standards: When your (valid) syntax doesn't properly express what it does, then your choice of syntax is bad. In your example, it would be better to use some function like

        template T* makeCArrayOfLength(size_t length) { return new T[length]; }

        whereas the functionality you invoked should be represented by

        template T* makeObjectFromValue(T const& value) { return new T(value); }

        That syntax not only will give you much better insight on what you are doing, it might also cause compiler warnings or errors when used incorrectly. Of course, it's a little more effort to write

        _TCHAR *buffer = makeCArrayOfLength<_TCHAR>(buffersize);

        But that effort pays off in the long run.

        GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

        G 1 Reply Last reply
        0
        • D DJ van Wyk

          It is probably possible that some UML somewhere will cater for that... Do what I mean, not what I say.

          My plan is to live forever ... so far so good

          Greg UtasG Offline
          Greg UtasG Offline
          Greg Utas
          wrote on last edited by
          #7

          :laugh: UML is good for documenting something complicated after it has stabilized.

          <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
          <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

          1 Reply Last reply
          0
          • S Stefan_Lang

            Yeah, I've seen that. Wasn't that the same posting which tried to express a pair using the syntax (a,b)? :doh:

            GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

            Greg UtasG Offline
            Greg UtasG Offline
            Greg Utas
            wrote on last edited by
            #8

            Yes, you contributed an answer to that one[^], where (a, b) was the syntax for a function definition's unnamed arguments!

            <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
            <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

            1 Reply Last reply
            0
            • S Stefan_Lang

              That's one of the problems that don't fit modern coding standards: When your (valid) syntax doesn't properly express what it does, then your choice of syntax is bad. In your example, it would be better to use some function like

              template T* makeCArrayOfLength(size_t length) { return new T[length]; }

              whereas the functionality you invoked should be represented by

              template T* makeObjectFromValue(T const& value) { return new T(value); }

              That syntax not only will give you much better insight on what you are doing, it might also cause compiler warnings or errors when used incorrectly. Of course, it's a little more effort to write

              _TCHAR *buffer = makeCArrayOfLength<_TCHAR>(buffersize);

              But that effort pays off in the long run.

              GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

              G Offline
              G Offline
              Gary R Wheeler
              wrote on last edited by
              #9

              To my mind, the code I wrote should have triggered a compiler diagnostic. The expression on the left side of the assignment operator is a pointer to _TCHAR while the right side is a single _TCHAR constructed from the value buffer_size. Barring perversions of the assignment operator, those two aren't the same thing. Of course, I am using a very old version of Visual Studio for this project, so...

              Software Zen: delete this;

              S 1 Reply Last reply
              0
              • G Gary R Wheeler

                To my mind, the code I wrote should have triggered a compiler diagnostic. The expression on the left side of the assignment operator is a pointer to _TCHAR while the right side is a single _TCHAR constructed from the value buffer_size. Barring perversions of the assignment operator, those two aren't the same thing. Of course, I am using a very old version of Visual Studio for this project, so...

                Software Zen: delete this;

                S Offline
                S Offline
                Stefan_Lang
                wrote on last edited by
                #10

                Unfortunately, new creates an object on the heap, and it does return a pointer. That corresponds to the left hand side. Also, it's not obvious to the compiler to understand what you intended. If you had constructed a class instance instead, it would be quite reasonable. While creating an integral type on the heap is quite unusual, it might still make sense if that code is part of a template implementation:

                template
                T* copy(T& const source) {
                return new T(source);
                }

                This code works for any kind of class, but also for integral types. So why should the compiler complain? However, the crux of the problem is that C/C++ treat {addreess to first element of array} the same as {address of object}. It doesn't differentiate the two, and that is why your assignment doesn't even raise a warning.

                GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

                G 1 Reply Last reply
                0
                • S Stefan_Lang

                  Unfortunately, new creates an object on the heap, and it does return a pointer. That corresponds to the left hand side. Also, it's not obvious to the compiler to understand what you intended. If you had constructed a class instance instead, it would be quite reasonable. While creating an integral type on the heap is quite unusual, it might still make sense if that code is part of a template implementation:

                  template
                  T* copy(T& const source) {
                  return new T(source);
                  }

                  This code works for any kind of class, but also for integral types. So why should the compiler complain? However, the crux of the problem is that C/C++ treat {addreess to first element of array} the same as {address of object}. It doesn't differentiate the two, and that is why your assignment doesn't even raise a warning.

                  GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

                  G Offline
                  G Offline
                  Gary R Wheeler
                  wrote on last edited by
                  #11

                  Aha! Thanks for the explanation. I sometimes forget subtleties because I'm constantly switching back and forth between C++ and C#.

                  Software Zen: delete this;

                  N 1 Reply Last reply
                  0
                  • M Member 9167057

                    C++ tried it's best to be compatible with C at the beginning, including it's idiosyncrasies. What's the point in the compiler guessing what the programmer's intention might be?

                    J Offline
                    J Offline
                    John R Shaw
                    wrote on last edited by
                    #12

                    I do not think a compiler should be guessing at what a programmer's intention should be. It should give them a warning (or error) that what they are asking makes no since. The compilers job is to turn your text into a program that runs on the given platform. There are two major issues with the compiler making dissensions for you: 1) You are not learning how to tell it what to do. 2) Your are learning that even if you do not understand how it works, that someone (way smarter than you) has figured out how to make it work - even if you don't. The main problem is that their solution to the problem (#2) may result in a solution that breaks what you intended. You'll never become an expert in the language of your choice if the compiler is deciding what you intended to do, as apposed to what you actually told it to do.

                    INTP "Program testing can be used to show the presence of bugs, but never to show their absence." - Edsger Dijkstra "I have never been lost, but I will admit to being confused for several weeks. " - Daniel Boone

                    N K 2 Replies Last reply
                    0
                    • G Gary R Wheeler

                      Aha! Thanks for the explanation. I sometimes forget subtleties because I'm constantly switching back and forth between C++ and C#.

                      Software Zen: delete this;

                      N Offline
                      N Offline
                      Nelek
                      wrote on last edited by
                      #13

                      Stefan_Lang wrote:

                      However, the crux of the problem is that C/C++ treat {addreess to first element of array} the same as {address of object}. It doesn't differentiate the two, and that is why your assignment doesn't even raise a warning.

                      const char *c = "Hello world!";

                      std::cout << "*c = " << *c << "\n";
                      std::cout << "size of *c = " << sizeof *c << "\n";
                      std::cout << "c[0] = " << c[0] << "\n";
                      std::cout << "size of c[0] = " << sizeof c[0] << "\n";

                      // versus
                      std::cout << "c = " << c << "\n";
                      std::cout << "size of c = " << sizeof c << "\n";
                      std::cout << "&c[0] = " << &c[0] << "\n";
                      std::cout << "size of &c[0] = " << sizeof &c[0] << "\n";

                      M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                      1 Reply Last reply
                      0
                      • J John R Shaw

                        I do not think a compiler should be guessing at what a programmer's intention should be. It should give them a warning (or error) that what they are asking makes no since. The compilers job is to turn your text into a program that runs on the given platform. There are two major issues with the compiler making dissensions for you: 1) You are not learning how to tell it what to do. 2) Your are learning that even if you do not understand how it works, that someone (way smarter than you) has figured out how to make it work - even if you don't. The main problem is that their solution to the problem (#2) may result in a solution that breaks what you intended. You'll never become an expert in the language of your choice if the compiler is deciding what you intended to do, as apposed to what you actually told it to do.

                        INTP "Program testing can be used to show the presence of bugs, but never to show their absence." - Edsger Dijkstra "I have never been lost, but I will admit to being confused for several weeks. " - Daniel Boone

                        N Offline
                        N Offline
                        Nelek
                        wrote on last edited by
                        #14

                        John R. Shaw wrote:

                        It should give them a warning (or error) that what they are asking makes no since.

                        I suppose you wanted to say "makes no sense"?

                        M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                        1 Reply Last reply
                        0
                        • G Gary R Wheeler

                          I've been debugging my first Windows shell extension, and just realized the problem with the following:

                          _TCHAR *buffer = new _TCHAR(buffer_size);

                          No compiler warnings or errors either.

                          Software Zen: delete this;

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #15

                          Except that in C++ that is a valid use of the new operator. See new Operator (C++) | Microsoft Docs[^].

                          1 Reply Last reply
                          0
                          • G Gary R Wheeler

                            I've been debugging my first Windows shell extension, and just realized the problem with the following:

                            _TCHAR *buffer = new _TCHAR(buffer_size);

                            No compiler warnings or errors either.

                            Software Zen: delete this;

                            M Offline
                            M Offline
                            Marc Clifton
                            wrote on last edited by
                            #16

                            So for the C++ illiterate, what's wrong with that line of code? Or did you mean new _TCHAR[buffer_size]; ?

                            Latest Articles:
                            Abusing Extension Methods, Null Continuation, and Null Coalescence Operators

                            Greg UtasG 1 Reply Last reply
                            0
                            • M Marc Clifton

                              So for the C++ illiterate, what's wrong with that line of code? Or did you mean new _TCHAR[buffer_size]; ?

                              Latest Articles:
                              Abusing Extension Methods, Null Continuation, and Null Coalescence Operators

                              Greg UtasG Offline
                              Greg UtasG Offline
                              Greg Utas
                              wrote on last edited by
                              #17

                              Precisely. As written, it casts buffer_size as a _TCHAR and allocates only one of them.

                              Robust Services Core | Software Techniques for Lemmings | Articles

                              <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                              <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                              1 Reply Last reply
                              0
                              • J John R Shaw

                                I do not think a compiler should be guessing at what a programmer's intention should be. It should give them a warning (or error) that what they are asking makes no since. The compilers job is to turn your text into a program that runs on the given platform. There are two major issues with the compiler making dissensions for you: 1) You are not learning how to tell it what to do. 2) Your are learning that even if you do not understand how it works, that someone (way smarter than you) has figured out how to make it work - even if you don't. The main problem is that their solution to the problem (#2) may result in a solution that breaks what you intended. You'll never become an expert in the language of your choice if the compiler is deciding what you intended to do, as apposed to what you actually told it to do.

                                INTP "Program testing can be used to show the presence of bugs, but never to show their absence." - Edsger Dijkstra "I have never been lost, but I will admit to being confused for several weeks. " - Daniel Boone

                                K Offline
                                K Offline
                                kalberts
                                wrote on last edited by
                                #18

                                One major difference between the TCP/IP protocol suite and the OSI protocol suite is that the former asks you to try to make sense of whatever you receive, one way or the other. OSI follows the principle that a protocol error is fatal, you cancel the connection. Disconnect is mandatory; if you continue operation trying to keep it going, then you are not conformant to the standard. Those sloppy, haphazard implementations are kicked out. If you want to exchange data, you better do it in the proper way! Of course it makes it more difficult to be an eager student who has not yet learnt proper behavior; before he goes out in the wide open world he must know what to do. The Internet lenient philosophy is fair enough while you are still playing in the sand pit, but not when you grow up. Programming languages are similar. They should define clearly what you can and cannot do. They should specify clearly all the issues that the compiler is required to detect, those that the generated code / runtime system is required to detect, and those that cannot reasonably be detected neither at compile time nor run time but is nevertheless an error. I know of one language specifications that includes all three, the Z.200 CHILL language. Unfortunately, CHILL never made it as a mainstream language (nobody really tried to make it!) - it was a language design of excellent quality. But I guess most programmers moving from C to CHILL would feel the strict discipline as a straightjacket.

                                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