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. What's the story with Hungarian Notation these days?

What's the story with Hungarian Notation these days?

Scheduled Pinned Locked Moved The Lounge
csharpc++question
50 Posts 16 Posters 0 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.
  • E Ennis Ray Lynch Jr

    Ah, but that is a prefix, and no prefixes are allowed :) Amazing how you can hear that argument from people that can justify using the prefix _ but no other prefix, not saying that you do, I get it. But come on, if you are going to prefix, use m. It has a meaning. I really think MS choose _ because they intentionally didn't want to use m. Personally, I use m. I just hate the "justification" for _ so I definitely understand and desire the need to know whether it is a member or a local.

    Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. I also do Android Programming as I find it a refreshing break from the MS. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost

    J Offline
    J Offline
    jschell
    wrote on last edited by
    #28

    Ennis Ray Lynch, Jr. wrote:

    I really think MS choose _ because they intentionally didn't want to use m.

    Hungarian notation although it existed before Microsoft was basically popularized by that company specifically in relation to C but it was used in C++ as well. And since Microsoft has long term employees, and long time employees tend to get promoted, one might presume that one or more employees preferred it that way. One might suppose that the ANSI C standard had some influence on the choice of underscore since a prefix of two underscores is specifically reserved for certain usages in C. And so certain developers might have thought that using one underscore for Microsoft specific code was appropriate since it wasn't ANSI C but wasn't user code either. And that usage was propagated.

    1 Reply Last reply
    0
    • C Clifford Nelson

      Personally I like the underscore for private variables. Makes them easy to find, and you know they are private class level. ReSharper enforces it. However when I was at Intel, I lost the battle to prefix with an underscore. Of course I was just a contractor, and there was an ex-contractor/new employee, who seemed like to take any position that was the opposite of mine, just to be an a$$. I think he did not appreciate that I did not think he was god of programming.

      J Offline
      J Offline
      jschell
      wrote on last edited by
      #29

      Clifford Nelson wrote:

      Personally I like the underscore for private variables. Makes them easy to find, and you know they are private class level.

      If you have a significant problem finding your private variables then it would suggest to me that perhaps there is a problem with your classes. Same thing is true if you cannot identify a variable within a class without it. The cases range between the following two extremes but still are relevant. 1. You have never seen the class before. In this case the most significant problem is identifying what the class does and what the implementation is doing. 2. You are very familiar with the class. So you should know what the variables are. Of course if you have classes with hundreds of methods or methods with thousands of lines then identifying private variables is a problem. But what is more of a problem is that the classes and/or methods are too big.

      C 1 Reply Last reply
      0
      • K Kevin Marois

        I'v been coding for 25 years. Camel case is a throwback from the days when all variables has to start with a lowercase letter.

        If it's not broken, fix it until it is

        J Offline
        J Offline
        jschell
        wrote on last edited by
        #30

        Kevin Marois wrote:

        Camel case is a throwback from the days when all variables has to start with a lowercase letter.

        I doubt that is an accurate theory for the origin. http://en.wikipedia.org/wiki/CamelCase#Background:_multi-word_identifiers[^]

        1 Reply Last reply
        0
        • _ _beauw_

          I don't think that the fundamental aspects of the C/C++ type system that led to Hungarian notation have really changed. At least, this is true in the realm of unmanaged C++. Hungarian notation didn't simply go out of style... it was (and is) a product of the Windows API's design.

          J Offline
          J Offline
          jschell
          wrote on last edited by
          #31

          _beauw_ wrote:

          I don't think that the fundamental aspects of the C/C++ type system that led to Hungarian notation have really changed.

          I suspect that is wrong. C used untyped parameter passing. Thus even if the method was expecting a int and only a int you could pass a pointer to it. Hungarian lessened the chance of that happening. Additionally there were no IDEs nor online documentation. If you wanted to know what a method definition was you had the following choices 1. Look at the written documentation 2. Find the code in the code base. This was only possible if one had the source. And wasn't necessarily fast even then. 3. Find an example that already used it. With hungarian the last case would provide all of the information about the method. Without it one then would need to look up each of the relevant variables.

          _ 1 Reply Last reply
          0
          • J jschell

            _beauw_ wrote:

            I don't think that the fundamental aspects of the C/C++ type system that led to Hungarian notation have really changed.

            I suspect that is wrong. C used untyped parameter passing. Thus even if the method was expecting a int and only a int you could pass a pointer to it. Hungarian lessened the chance of that happening. Additionally there were no IDEs nor online documentation. If you wanted to know what a method definition was you had the following choices 1. Look at the written documentation 2. Find the code in the code base. This was only possible if one had the source. And wasn't necessarily fast even then. 3. Find an example that already used it. With hungarian the last case would provide all of the information about the method. Without it one then would need to look up each of the relevant variables.

            _ Offline
            _ Offline
            _beauw_
            wrote on last edited by
            #32

            Yeah, that's what I meant. So many things that are really different seem the same to the compiler when calling the Windows APIs. This has never really been cleaned up. Even .NET developers call into these same APIs pretty frequently and they face the same issue. If you take a look at PInvoke.net[^], .NET developers have come up with declarations allowing the Windows API to be called from their code. These declarations use the IntPtr type over and over again for all sorts of different things. So, even these .NET developers have to deal with the inherent problems that led to Hungarian notation. They don't seem to use Hungarian notation as much as people who do Windows programming in C, but the issues that led to it are still there.

            J 1 Reply Last reply
            0
            • J jschell

              Clifford Nelson wrote:

              Personally I like the underscore for private variables. Makes them easy to find, and you know they are private class level.

              If you have a significant problem finding your private variables then it would suggest to me that perhaps there is a problem with your classes. Same thing is true if you cannot identify a variable within a class without it. The cases range between the following two extremes but still are relevant. 1. You have never seen the class before. In this case the most significant problem is identifying what the class does and what the implementation is doing. 2. You are very familiar with the class. So you should know what the variables are. Of course if you have classes with hundreds of methods or methods with thousands of lines then identifying private variables is a problem. But what is more of a problem is that the classes and/or methods are too big.

              C Offline
              C Offline
              Clifford Nelson
              wrote on last edited by
              #33

              That is my preference, and obviously it has a lot of support since Refactor recommends. As far as significant problem, those are your words, not mine.

              J 1 Reply Last reply
              0
              • _ _beauw_

                Yeah, that's what I meant. So many things that are really different seem the same to the compiler when calling the Windows APIs. This has never really been cleaned up. Even .NET developers call into these same APIs pretty frequently and they face the same issue. If you take a look at PInvoke.net[^], .NET developers have come up with declarations allowing the Windows API to be called from their code. These declarations use the IntPtr type over and over again for all sorts of different things. So, even these .NET developers have to deal with the inherent problems that led to Hungarian notation. They don't seem to use Hungarian notation as much as people who do Windows programming in C, but the issues that led to it are still there.

                J Offline
                J Offline
                jschell
                wrote on last edited by
                #34

                _beauw_ wrote:

                This has never really been cleaned up. Even .NET developers call into these same APIs pretty frequently and they face the same issue. If you take a look at PInvoke.net[^], .NET developers have come up with declarations allowing the Windows API to be called from their code. These declarations use the IntPtr type over and over again for all sorts of different things.

                Not exactly sure what you are referring to but I suspect a majority of C# developers never use pinvoke. And of the remainder that do many do not use it frequently. And I would like to think that of those that do use it frequently (and unfrequently) that they wrap it in a C# API of their own creation. Thus there would not be any more ambiguity in the usage for them or others at that point.

                _ 1 Reply Last reply
                0
                • J jschell

                  _beauw_ wrote:

                  This has never really been cleaned up. Even .NET developers call into these same APIs pretty frequently and they face the same issue. If you take a look at PInvoke.net[^], .NET developers have come up with declarations allowing the Windows API to be called from their code. These declarations use the IntPtr type over and over again for all sorts of different things.

                  Not exactly sure what you are referring to but I suspect a majority of C# developers never use pinvoke. And of the remainder that do many do not use it frequently. And I would like to think that of those that do use it frequently (and unfrequently) that they wrap it in a C# API of their own creation. Thus there would not be any more ambiguity in the usage for them or others at that point.

                  _ Offline
                  _ Offline
                  _beauw_
                  wrote on last edited by
                  #35

                  I'm a .NET developer; in fact, it's my main job right now. I don't use PInvoke all that frequently, but I probably do use it (i.e. use the Windows API) more than any other API besides the .NET Framework itself. Yes, I do wrap up those low-level calls pretty frequently. I have to write the wrapper, though, and in doing that I face all of those same old issues of weak typing. Besides that, PInvoke is just part of the story. The larger issue (in my opinion, at least) is that the APIs themselves still are constructed and declared in this way. When Microsoft comes out with something new, like DWM for example, they basically construct its API similarly to the way they always have. Here are some examples from the DWM header file (DWMAPI.H):

                  DWMAPI DwmSetWindowAttribute(HWND, DWORD, LPCVOID, DWORD);
                  DWMAPI DwmExtendFrameIntoClientArea(HWND,const MARGINS*);

                  Looking at that sort of thing, I do not perceive that the way in which Microsoft declares their API functions has changed all that much. They are still using HWND, for example, which is really just another integer to the compiler. Is this why people are using Hungarian Notation? Yes, it is for some of them. For others, Hungarian Notation is a habit, or just something they picked up from others, and I agree that that's really pretty silly.

                  J 1 Reply Last reply
                  0
                  • _ _beauw_

                    I'm a .NET developer; in fact, it's my main job right now. I don't use PInvoke all that frequently, but I probably do use it (i.e. use the Windows API) more than any other API besides the .NET Framework itself. Yes, I do wrap up those low-level calls pretty frequently. I have to write the wrapper, though, and in doing that I face all of those same old issues of weak typing. Besides that, PInvoke is just part of the story. The larger issue (in my opinion, at least) is that the APIs themselves still are constructed and declared in this way. When Microsoft comes out with something new, like DWM for example, they basically construct its API similarly to the way they always have. Here are some examples from the DWM header file (DWMAPI.H):

                    DWMAPI DwmSetWindowAttribute(HWND, DWORD, LPCVOID, DWORD);
                    DWMAPI DwmExtendFrameIntoClientArea(HWND,const MARGINS*);

                    Looking at that sort of thing, I do not perceive that the way in which Microsoft declares their API functions has changed all that much. They are still using HWND, for example, which is really just another integer to the compiler. Is this why people are using Hungarian Notation? Yes, it is for some of them. For others, Hungarian Notation is a habit, or just something they picked up from others, and I agree that that's really pretty silly.

                    J Offline
                    J Offline
                    jschell
                    wrote on last edited by
                    #36

                    _beauw_ wrote:

                    I'm a .NET developer; in fact, it's my main job right now. I don't use PInvoke all that frequently, but I probably do use it (i.e. use the Windows API) more than any other API besides the .NET Framework itself. Yes, I do wrap up those low-level calls pretty frequently. I have to write the wrapper, though, and in doing that I face all of those same old issues of weak typing.

                    When you write a wrapper you are using a new API method of which you must become very familar. Thus you will be using a source (documentation) that tells you the exactly what information is needed. Thus there can be no benifit to you using hungarian notation at that time because you are using the documentation itself. Subsequent to that you use your wrapper API. And your wrapper API (unless you did it wrong) is strongly typed. You don't use the pinvoke API at all. So hungarian notation has no benefit in this context. If you, or someone else needs to maintain the pinvoke code later then they are, again, going to need to use the API documentation. Otherwise there is no point in maintaining the code. The above is a representation of usage scenarios if the a pinvoke API is wrapped rather than just used. If it is not wrapped then type usage is more of a problem however the real problem is that the API is not correctly wrapped.

                    _beauw_ wrote:

                    Here are some examples from the DWM header file (DWMAPI.H):

                    What does that have to do with anything? But if you want to use that API - then wrap it. And then it falls into exactly what I said above.

                    _ 1 Reply Last reply
                    0
                    • C Clifford Nelson

                      That is my preference, and obviously it has a lot of support since Refactor recommends. As far as significant problem, those are your words, not mine.

                      J Offline
                      J Offline
                      jschell
                      wrote on last edited by
                      #37

                      Clifford Nelson wrote:

                      That is my preference,

                      There is however a difference between expressing an opinion and attempting to rationalize that as being the best way.

                      Clifford Nelson wrote:

                      and obviously it has a lot of support since Refactor recommends

                      That of course is a rationalization. Unless of course you have some data that backs up with a survey of a large number of people.

                      Clifford Nelson wrote:

                      As far as significant problem, those are your words, not mine.

                      Nope. You said "Makes them easy to find, and you know they are private class level". So obviously that is your problem which you find this useful to solve. Myself I don't have that problem. I know which variables are class and local. So I don't need to solve a problem because none exists.

                      1 Reply Last reply
                      0
                      • J jschell

                        _beauw_ wrote:

                        I'm a .NET developer; in fact, it's my main job right now. I don't use PInvoke all that frequently, but I probably do use it (i.e. use the Windows API) more than any other API besides the .NET Framework itself. Yes, I do wrap up those low-level calls pretty frequently. I have to write the wrapper, though, and in doing that I face all of those same old issues of weak typing.

                        When you write a wrapper you are using a new API method of which you must become very familar. Thus you will be using a source (documentation) that tells you the exactly what information is needed. Thus there can be no benifit to you using hungarian notation at that time because you are using the documentation itself. Subsequent to that you use your wrapper API. And your wrapper API (unless you did it wrong) is strongly typed. You don't use the pinvoke API at all. So hungarian notation has no benefit in this context. If you, or someone else needs to maintain the pinvoke code later then they are, again, going to need to use the API documentation. Otherwise there is no point in maintaining the code. The above is a representation of usage scenarios if the a pinvoke API is wrapped rather than just used. If it is not wrapped then type usage is more of a problem however the real problem is that the API is not correctly wrapped.

                        _beauw_ wrote:

                        Here are some examples from the DWM header file (DWMAPI.H):

                        What does that have to do with anything? But if you want to use that API - then wrap it. And then it falls into exactly what I said above.

                        _ Offline
                        _ Offline
                        _beauw_
                        wrote on last edited by
                        #38

                        jschell wrote:

                        When you write a wrapper you are using a new API method of which you must become very familar. Thus you will be using a source (documentation) that tells you the exactly what information is needed. Thus there can be no benifit to you using hungarian notation at that time because you are using the documentation itself.

                        I've written little wrapper functions just to make sure that I call ReleaseDC(). That doesn't require much expertise. Often, I also do things to hide the ugliness of a Windows API function's signature (e.g. to allow passage of a Window instead of an untyped IntPtr). That also does not require expert-level knowledge. Not incidentally, the very same people who invented Hungarian Notation probably wrote their own wrappers in C and assembly language, and they still saw value in their little prefixes.

                        jschell wrote:

                        Subsequent to that you use your wrapper API. And your wrapper API (unless you did it wrong) is strongly typed.

                        That seems very simplistic. "Subsequent to that," I also maintain and expand my wrapper API... using things like IntPtr.

                        jschell wrote:

                        So hungarian notation has no benefit in this context.

                        I don't think it ever gave much of a real benefit, but my perception of the work that I do is that the original problem that led to it is still there. People have more opportunities to work at a higher level of abstraction... to mistake those opportunities for really fundamental change in the underlying composition of Windows is an error.

                        J 1 Reply Last reply
                        0
                        • _ _beauw_

                          jschell wrote:

                          When you write a wrapper you are using a new API method of which you must become very familar. Thus you will be using a source (documentation) that tells you the exactly what information is needed. Thus there can be no benifit to you using hungarian notation at that time because you are using the documentation itself.

                          I've written little wrapper functions just to make sure that I call ReleaseDC(). That doesn't require much expertise. Often, I also do things to hide the ugliness of a Windows API function's signature (e.g. to allow passage of a Window instead of an untyped IntPtr). That also does not require expert-level knowledge. Not incidentally, the very same people who invented Hungarian Notation probably wrote their own wrappers in C and assembly language, and they still saw value in their little prefixes.

                          jschell wrote:

                          Subsequent to that you use your wrapper API. And your wrapper API (unless you did it wrong) is strongly typed.

                          That seems very simplistic. "Subsequent to that," I also maintain and expand my wrapper API... using things like IntPtr.

                          jschell wrote:

                          So hungarian notation has no benefit in this context.

                          I don't think it ever gave much of a real benefit, but my perception of the work that I do is that the original problem that led to it is still there. People have more opportunities to work at a higher level of abstraction... to mistake those opportunities for really fundamental change in the underlying composition of Windows is an error.

                          J Offline
                          J Offline
                          jschell
                          wrote on last edited by
                          #39

                          _beauw_ wrote:

                          Not incidentally, the very same people who invented Hungarian Notation probably wrote their own wrappers in C and assembly language, and they still saw value in their little prefixes.

                          Assembly has nothing to do with the origins. C doesn't do type checking so the prefix, which embodies the type, allows the developer to manually verify the type. It has nothing to do with wrapping.

                          _beauw_ wrote:

                          That seems very simplistic. "Subsequent to that," I also maintain and expand my wrapper API... using things like IntPtr.

                          If you write a wrapper that take an IntPtr then you are not wrapping it.

                          _ 2 Replies Last reply
                          0
                          • J jschell

                            _beauw_ wrote:

                            Not incidentally, the very same people who invented Hungarian Notation probably wrote their own wrappers in C and assembly language, and they still saw value in their little prefixes.

                            Assembly has nothing to do with the origins. C doesn't do type checking so the prefix, which embodies the type, allows the developer to manually verify the type. It has nothing to do with wrapping.

                            _beauw_ wrote:

                            That seems very simplistic. "Subsequent to that," I also maintain and expand my wrapper API... using things like IntPtr.

                            If you write a wrapper that take an IntPtr then you are not wrapping it.

                            _ Offline
                            _ Offline
                            _beauw_
                            wrote on last edited by
                            #40

                            So what are you saying? That Hungarian Notation was really valuable once, but that fundamental changes have now made it worthless? I just don't agree on either count. If you're saying that I've been working at too low a level of abstraction, and that it has distorted my perspective, then my response is... "maybe so." :)

                            jschell wrote:

                            Assembly has nothing to do with the origins. C doesn't do type checking so the prefix, which embodies the type, allows the developer to manually verify the type.

                            C can most definitely do type checking. A well-constructed C API that wanted to distinguish between a 32-bit "double word" and a 32-bit "unsigned int" (as the Windows API seems to want to do) most definitely could, e.g.

                            typedef struct
                            {
                            unsigned int data;
                            } api_uint;

                            typedef struct
                            {
                            unsigned int data;
                            } api_dword;

                            Given these declarations, I cannot interchange instances of these two types in a C program. The following will not compile:

                            api_uint a;
                            api_dword b;
                            a=b;

                            Microsoft did not take such an approach, though. The Windows code shown below compiles without error or warning:

                            UINT uu;
                            DWORD dd;
                            uu=dd;

                            This is because Microsoft declared their "double word" and "unsigned integer" types using the preprocessor, not using the C type system. Why would Microsoft circumvent the C type system in this way? I have always suspected that they thought and coded this way because they were basically writing an assembly language API for assemblers that (not being compilers) had no notion of abstract data types (e.g. struct). Maybe you have a different theory! You say that "assembly has nothing to do" with this, but what I see in the Windows API is an assembly language API defined at a lower level of abstraction than even a good C API would be defined.

                            jschell wrote:

                            It has nothing to do with wrapping.

                            Really? I think that good C programming using the Windows API has everything to do with wrapping. The API is an assembly language API. Its associated C declarations are really just assembly language declarations in disguise. Despite your claims to the contrary, the C compiler will do type checking... except that it can't enforce type checking on an API designed without it. Considering the following function, which is an example of the sort of C-language wrapper that I had in mind:

                            void shellexec(const cha

                            1 Reply Last reply
                            0
                            • J jschell

                              _beauw_ wrote:

                              Not incidentally, the very same people who invented Hungarian Notation probably wrote their own wrappers in C and assembly language, and they still saw value in their little prefixes.

                              Assembly has nothing to do with the origins. C doesn't do type checking so the prefix, which embodies the type, allows the developer to manually verify the type. It has nothing to do with wrapping.

                              _beauw_ wrote:

                              That seems very simplistic. "Subsequent to that," I also maintain and expand my wrapper API... using things like IntPtr.

                              If you write a wrapper that take an IntPtr then you are not wrapping it.

                              _ Offline
                              _ Offline
                              _beauw_
                              wrote on last edited by
                              #41

                              So what are you saying? That Hungarian Notation was really valuable once, but that fundamental changes have now made it worthless? I just don't agree on either count. If you're saying that I've been working at too low a level of abstraction, and that it has distorted my perspective, then my response is... "maybe so." :)

                              jschell wrote:

                              Assembly has nothing to do with the origins. C doesn't do type checking so the prefix, which embodies the type, allows the developer to manually verify the type.

                              C can most definitely do type checking. A well-constructed C API that wanted to distinguish between a 32-bit "double word" and a 32-bit "unsigned int" (as the Windows API seems to want to do) most definitely could, e.g.

                              typedef struct
                              {
                              unsigned int data;
                              } api_uint;

                              typedef struct
                              {
                              unsigned int data;
                              } api_dword;

                              Given these declarations, I cannot interchange instances of these two types in a C program. The following will not compile:

                              api_uint a;
                              api_dword b;
                              a=b;

                              Microsoft did not take such an approach, though. The Windows code shown below compiles without error or warning:

                              UINT uu;
                              DWORD dd;
                              uu=dd;

                              This is because Microsoft declared their "double word" and "unsigned integer" types using the preprocessor, not using the C type system. Why would Microsoft circumvent the C type system in this way? I have always suspected that they thought and coded this way because they were basically writing an assembly language API for assemblers that (not being compilers) had no notion of abstract data types (e.g. struct). Maybe you have a different theory! You say that "assembly has nothing to do" with this, but what I see in the Windows API is an assembly language API defined at a lower level of abstraction than even a good C API would be defined.

                              jschell wrote:

                              It has nothing to do with wrapping.

                              Really? I think that good C programming using the Windows API has everything to do with wrapping. The API is an assembly language API. Its associated C declarations are really just assembly language declarations in disguise. Despite your claims to the contrary, the C compiler will do type checking... except that it can't enforce type checking on an API designed without it. Considering the following function, which is an example of the sort of C-language wrapper that I had in mind:

                              void shellexec(const

                              J 1 Reply Last reply
                              0
                              • _ _beauw_

                                So what are you saying? That Hungarian Notation was really valuable once, but that fundamental changes have now made it worthless? I just don't agree on either count. If you're saying that I've been working at too low a level of abstraction, and that it has distorted my perspective, then my response is... "maybe so." :)

                                jschell wrote:

                                Assembly has nothing to do with the origins. C doesn't do type checking so the prefix, which embodies the type, allows the developer to manually verify the type.

                                C can most definitely do type checking. A well-constructed C API that wanted to distinguish between a 32-bit "double word" and a 32-bit "unsigned int" (as the Windows API seems to want to do) most definitely could, e.g.

                                typedef struct
                                {
                                unsigned int data;
                                } api_uint;

                                typedef struct
                                {
                                unsigned int data;
                                } api_dword;

                                Given these declarations, I cannot interchange instances of these two types in a C program. The following will not compile:

                                api_uint a;
                                api_dword b;
                                a=b;

                                Microsoft did not take such an approach, though. The Windows code shown below compiles without error or warning:

                                UINT uu;
                                DWORD dd;
                                uu=dd;

                                This is because Microsoft declared their "double word" and "unsigned integer" types using the preprocessor, not using the C type system. Why would Microsoft circumvent the C type system in this way? I have always suspected that they thought and coded this way because they were basically writing an assembly language API for assemblers that (not being compilers) had no notion of abstract data types (e.g. struct). Maybe you have a different theory! You say that "assembly has nothing to do" with this, but what I see in the Windows API is an assembly language API defined at a lower level of abstraction than even a good C API would be defined.

                                jschell wrote:

                                It has nothing to do with wrapping.

                                Really? I think that good C programming using the Windows API has everything to do with wrapping. The API is an assembly language API. Its associated C declarations are really just assembly language declarations in disguise. Despite your claims to the contrary, the C compiler will do type checking... except that it can't enforce type checking on an API designed without it. Considering the following function, which is an example of the sort of C-language wrapper that I had in mind:

                                void shellexec(const

                                J Offline
                                J Offline
                                jschell
                                wrote on last edited by
                                #42

                                _beauw_ wrote:

                                So what are you saying? That Hungarian Notation was really valuable once, but that fundamental changes have now made it worthless?

                                It serves no purpose in C#, Java and for the most part C++. It has less value in C due to increased use of IDEs and more so with the increased ease of access to documentation.

                                _beauw_ wrote:

                                C can most definitely do type checking. A well-constructed C API that wanted to distinguish between a 32-bit "double word" and a 32-bit "unsigned int" (as the Windows API seems to want to do) most definitely could, e.g.

                                You are wrong or your phrasing is poorly done. C does not type check parameters. Whatever you put on to the stack is what is delivered to the method.

                                _beauw_ wrote:

                                Given these declarations, I cannot interchange instances ...

                                Method invocation is the problem now. However in early C compilers even assignment was allowed between different types.

                                _beauw_ wrote:

                                I agree... but if I expand my API, I'll need to write the underlying implementation. That's where I end up using unsafe types like IntPtr.

                                No idea what you are talking about. Stating it again, if you write a wrapper in C# then the following is true. 1. When you INITIALLY write it there is no gain from hungarian because you MUST know the C API to write the wrapper in the first place. 2. The USERS of your C# api do not need hungarian because the C# API itself is type safe. 3. The maintenance developer who must maintain the wrapper would only run into problems if the wrapper is over complex. And the problem then is not with type resolution but with the failure to wrap the C API in the first place in such a way that it was simple to use. (Adding new C methods falls into 1 above.)

                                _ 1 Reply Last reply
                                0
                                • J jschell

                                  _beauw_ wrote:

                                  So what are you saying? That Hungarian Notation was really valuable once, but that fundamental changes have now made it worthless?

                                  It serves no purpose in C#, Java and for the most part C++. It has less value in C due to increased use of IDEs and more so with the increased ease of access to documentation.

                                  _beauw_ wrote:

                                  C can most definitely do type checking. A well-constructed C API that wanted to distinguish between a 32-bit "double word" and a 32-bit "unsigned int" (as the Windows API seems to want to do) most definitely could, e.g.

                                  You are wrong or your phrasing is poorly done. C does not type check parameters. Whatever you put on to the stack is what is delivered to the method.

                                  _beauw_ wrote:

                                  Given these declarations, I cannot interchange instances ...

                                  Method invocation is the problem now. However in early C compilers even assignment was allowed between different types.

                                  _beauw_ wrote:

                                  I agree... but if I expand my API, I'll need to write the underlying implementation. That's where I end up using unsafe types like IntPtr.

                                  No idea what you are talking about. Stating it again, if you write a wrapper in C# then the following is true. 1. When you INITIALLY write it there is no gain from hungarian because you MUST know the C API to write the wrapper in the first place. 2. The USERS of your C# api do not need hungarian because the C# API itself is type safe. 3. The maintenance developer who must maintain the wrapper would only run into problems if the wrapper is over complex. And the problem then is not with type resolution but with the failure to wrap the C API in the first place in such a way that it was simple to use. (Adding new C methods falls into 1 above.)

                                  _ Offline
                                  _ Offline
                                  _beauw_
                                  wrote on last edited by
                                  #43

                                  jschell wrote:

                                  It serves no purpose in C#, Java and for the most part C++.
                                  It has less value in C due to increased use of IDEs and more so with the increased ease of access to documentation.

                                  I've described a potential use for Hungarian Notation in C# in detail (to disambiguate the fundamental type of IntPtrs). People calling the Windows API from Java (if this is even done) would presumably face the same issues. Hungarian Notation has always been a part of Windows programming in C and C++... some people like it, some don't. If you're one of the people who doesn't like it, your argument is not with me, it's with Charles Simonyi and his colleagues on the original Windows team. IDEs, good documentation, and high levels of developer knowledge are all good things. I'd venture to say that Simonyi had at least the second and third of these at his disposal, and he still found Hungarian Notation useful.

                                  jschell wrote:

                                  C does not type check parameters. Whatever you put on to the stack is what is delivered to the method.

                                  This is just not true. It's possible to force behavior like that using typecasts (even C# has its little workarounds), but the behavior you're describing is fundamentally opposed to how C actually operates. C is not an assembly language. Its functions have declared signatures, and C fully supports the construction of ADTs. If I declare my function as taking an instance of a certain struct, for example, it will not accept an instance of some other struct, even if the two types have an identical layout. The code will result in a compile-time error. I provided example code for this already. Simple types in C have their own checks as well. The level of automatic coercion and conversion that can happen is really pretty similar to C#. I can assign an int into a float, or vice-versa, because both types are numeric. I cannot assign an int into an int*; these types are fundamentally different, and the C compiler knows it. All of this can be circumvented, as can many of (for example) the type checks that happen by default in C#. As I noted already, the Windows API does not fully use the type-checking capabilities of the C language. I posited that this was because it's really an assembly language API, and you rejected that idea. I have not arrived at an alternate explanation- perhaps you can

                                  J 1 Reply Last reply
                                  0
                                  • R RugbyLeague

                                    I use Bulgarian notation

                                    _ Offline
                                    _ Offline
                                    _beauw_
                                    wrote on last edited by
                                    #44

                                    So do you type your programs in with a specially crafted umbrella?

                                    R 1 Reply Last reply
                                    0
                                    • _ _beauw_

                                      So do you type your programs in with a specially crafted umbrella?

                                      R Offline
                                      R Offline
                                      RugbyLeague
                                      wrote on last edited by
                                      #45

                                      Doesn't everybody? :~

                                      1 Reply Last reply
                                      0
                                      • _ _beauw_

                                        jschell wrote:

                                        It serves no purpose in C#, Java and for the most part C++.
                                        It has less value in C due to increased use of IDEs and more so with the increased ease of access to documentation.

                                        I've described a potential use for Hungarian Notation in C# in detail (to disambiguate the fundamental type of IntPtrs). People calling the Windows API from Java (if this is even done) would presumably face the same issues. Hungarian Notation has always been a part of Windows programming in C and C++... some people like it, some don't. If you're one of the people who doesn't like it, your argument is not with me, it's with Charles Simonyi and his colleagues on the original Windows team. IDEs, good documentation, and high levels of developer knowledge are all good things. I'd venture to say that Simonyi had at least the second and third of these at his disposal, and he still found Hungarian Notation useful.

                                        jschell wrote:

                                        C does not type check parameters. Whatever you put on to the stack is what is delivered to the method.

                                        This is just not true. It's possible to force behavior like that using typecasts (even C# has its little workarounds), but the behavior you're describing is fundamentally opposed to how C actually operates. C is not an assembly language. Its functions have declared signatures, and C fully supports the construction of ADTs. If I declare my function as taking an instance of a certain struct, for example, it will not accept an instance of some other struct, even if the two types have an identical layout. The code will result in a compile-time error. I provided example code for this already. Simple types in C have their own checks as well. The level of automatic coercion and conversion that can happen is really pretty similar to C#. I can assign an int into a float, or vice-versa, because both types are numeric. I cannot assign an int into an int*; these types are fundamentally different, and the C compiler knows it. All of this can be circumvented, as can many of (for example) the type checks that happen by default in C#. As I noted already, the Windows API does not fully use the type-checking capabilities of the C language. I posited that this was because it's really an assembly language API, and you rejected that idea. I have not arrived at an alternate explanation- perhaps you can

                                        J Offline
                                        J Offline
                                        jschell
                                        wrote on last edited by
                                        #46

                                        _beauw_ wrote:

                                        I'd venture to say that Simonyi had at least the second and third of these at his disposal, and he still found Hungarian Notation useful.

                                        He had no more access to documentation at that time than any other developer did.

                                        _beauw_ wrote:

                                        This is just not true. It's possible to force behavior like that using typecasts (even C# has its little workarounds), but the behavior you're describing is fundamentally opposed to how C actually operates.

                                        C methods do not do type checking. C compilers can use prototypes in headers to do type checking HOWEVER. 1. The prototype must be available. 2. The prototype must be correct. And the above is irrelevant because it did NOT exist when hungarian was created.

                                        _beauw_ wrote:

                                        Some of your earlier comments make me think that you believe this to still be the case on modern C compilers

                                        And your comments make me think that you forgot the point of the thread. At one time there were non-trivial problems for which hungarian notation seemed to offer something like a solution. NOW, especially with languages created after C, some of the problems do NOT exist. And the remaining problems, even the rationalized ones, are trivial.

                                        _beauw_ wrote:

                                        In item 1, what you're saying is that the people who actually have to deal with ambiguous Windows API types are just so knowledgeable that they don't need Hungarian Notation

                                        Something is wrong with that statement. When you are writing a wrapper for the first time you are looking at the windows API methods. If you find that it is ambiguous when you are looking at the documentation itself then that is another discussion. So, I can only suppose that you are referring to the hungarian notation that Microsoft uses in their API. Which has nothing to do with my point. My point is about the code that you write to create the wrapper. You don't need to create new hungarian named id variables at that time to understand the Microsoft API.

                                        _beauw_ wrote:

                                        They faced the same basic issues of type ambiguity,

                                        I wrote C code for years before there was an ANSI standard. I know exactly what sort of ambiguities could arise from using others APIs as well as using my own. And no the same problems do not exist now. Not

                                        _ 1 Reply Last reply
                                        0
                                        • J jschell

                                          _beauw_ wrote:

                                          I'd venture to say that Simonyi had at least the second and third of these at his disposal, and he still found Hungarian Notation useful.

                                          He had no more access to documentation at that time than any other developer did.

                                          _beauw_ wrote:

                                          This is just not true. It's possible to force behavior like that using typecasts (even C# has its little workarounds), but the behavior you're describing is fundamentally opposed to how C actually operates.

                                          C methods do not do type checking. C compilers can use prototypes in headers to do type checking HOWEVER. 1. The prototype must be available. 2. The prototype must be correct. And the above is irrelevant because it did NOT exist when hungarian was created.

                                          _beauw_ wrote:

                                          Some of your earlier comments make me think that you believe this to still be the case on modern C compilers

                                          And your comments make me think that you forgot the point of the thread. At one time there were non-trivial problems for which hungarian notation seemed to offer something like a solution. NOW, especially with languages created after C, some of the problems do NOT exist. And the remaining problems, even the rationalized ones, are trivial.

                                          _beauw_ wrote:

                                          In item 1, what you're saying is that the people who actually have to deal with ambiguous Windows API types are just so knowledgeable that they don't need Hungarian Notation

                                          Something is wrong with that statement. When you are writing a wrapper for the first time you are looking at the windows API methods. If you find that it is ambiguous when you are looking at the documentation itself then that is another discussion. So, I can only suppose that you are referring to the hungarian notation that Microsoft uses in their API. Which has nothing to do with my point. My point is about the code that you write to create the wrapper. You don't need to create new hungarian named id variables at that time to understand the Microsoft API.

                                          _beauw_ wrote:

                                          They faced the same basic issues of type ambiguity,

                                          I wrote C code for years before there was an ANSI standard. I know exactly what sort of ambiguities could arise from using others APIs as well as using my own. And no the same problems do not exist now. Not

                                          _ Offline
                                          _ Offline
                                          _beauw_
                                          wrote on last edited by
                                          #47

                                          Microsoft C 3.0 was released in 1985, the same year as Windows 1.0, and it supported function prototypes. It was used to write Windows code inside Microsoft, well before Windows 1.0 even shipped. Microsoft never intended any version of C that lacked function prototypes to be used for Windows development. The fact that the standard was unpublished until 1989 does not change these facts. Your assertion that Hungarian Notation is basically an outgrowth of the pre-ANSI "K&R" C language is an interesting one (and it might even have been true for you, if you didn't have access to Microsoft C 3.0) but it's not backed up by actual history. K&R C (which is the version of the language that lacks function prototypes) has little if anything to do with Windows; I've never seen K&R Windows C and I don't think any of the Windows codebase was ever K&R C. This timeline is further elaborated here[^]. Even Wikipedia[^] mentions that Microsoft C 3.0 was basically an ANSI C compiler before its time.

                                          jschell wrote:

                                          Which of course is completely missing my original point. If you need to use a API method - create a wrapper. Then you would never be hovering over a IntPtr in the first place.

                                          When .NET code wants to call an API function, it's necessary to prototype the API function in the .NET language. The developer writing the prototype gets to select the names of the formal parameters. This developer should select names that are meaningful (even if you don't think these DLLImport declarations will be worked with very often). Hungarian Notation seems like the obvious way to do this. It's pretty widely understood, and most of these declarations were originally translated from their C equivalents, which already have Hungarian-style names. Then .NET code (likely a wrapper) must be written around these DLLImport declarations. This code will presumably declare IntPtr variables to pass into the Windows API functions. Again, one faces the issue of augmenting the lack of information conveyed by these vari

                                          J 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