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.
  • _ _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
                              • _ _beauw_

                                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 Offline
                                J Offline
                                jschell
                                wrote on last edited by
                                #48

                                _beauw_ wrote:

                                Microsoft C 3.0 was released in 1985, the same year as Windows 1.0, and it supported function prototypes.

                                Which doesn't alter the fact that the use was entirely optional. So if you didn't include the header your code still worked - if you got the call correct. And are you sure that that version of windows did parameter validation? There is a difference between validating the method and validating the parameters.

                                _beauw_ wrote:

                                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.

                                I used Microsoft C version 3.0. Simonyi joined Microsoft in 1981. Simonyi came up with the idea before joining Microsoft. Are you claiming that prototypes were widely available before 1981 and Simonyi developed hungarian notation despite that? Others who think that hungarion notation is no longer useful. http://en.wikipedia.org/wiki/Hungarian_notation#Notable_opinions[^] Including Microsoft: http://msdn.microsoft.com/en-us/library/ms229045.aspx[^]

                                _beauw_ wrote:

                                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).

                                So in terms of prototyping the the pinvoke method itself - the developer should choose a name that most closely mimics that of the documentation for the method itself. Regardless of what that name is.

                                _beauw_ wrote:

                                Hungarian Notation seems like the obvious way to do this

                                The obvious way is to use exactly the same name as that used in the documentation for the method.

                                _ 1 Reply Last reply
                                0
                                • J jschell

                                  _beauw_ wrote:

                                  Microsoft C 3.0 was released in 1985, the same year as Windows 1.0, and it supported function prototypes.

                                  Which doesn't alter the fact that the use was entirely optional. So if you didn't include the header your code still worked - if you got the call correct. And are you sure that that version of windows did parameter validation? There is a difference between validating the method and validating the parameters.

                                  _beauw_ wrote:

                                  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.

                                  I used Microsoft C version 3.0. Simonyi joined Microsoft in 1981. Simonyi came up with the idea before joining Microsoft. Are you claiming that prototypes were widely available before 1981 and Simonyi developed hungarian notation despite that? Others who think that hungarion notation is no longer useful. http://en.wikipedia.org/wiki/Hungarian_notation#Notable_opinions[^] Including Microsoft: http://msdn.microsoft.com/en-us/library/ms229045.aspx[^]

                                  _beauw_ wrote:

                                  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).

                                  So in terms of prototyping the the pinvoke method itself - the developer should choose a name that most closely mimics that of the documentation for the method itself. Regardless of what that name is.

                                  _beauw_ wrote:

                                  Hungarian Notation seems like the obvious way to do this

                                  The obvious way is to use exactly the same name as that used in the documentation for the method.

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

                                  jschell wrote:

                                  Which doesn't alter the fact that the use was entirely optional. So if you didn't include the header your code still worked - if you got the call correct.

                                  That seems like a very odd (and uncommon) way to write code. I can't imagine too many people did that.

                                  jschell wrote:

                                  Simonyi joined Microsoft in 1981. Simonyi came up with the idea before joining Microsoft.
                                   
                                  Are you claiming that prototypes were widely available before 1981 and Simonyi developed hungarian notation despite that?

                                  No, I don't think prototypes were common in C before 1981. And I am sure that Simonyi's variable-naming style (which is all this really is) evolved over his entire career. What I am saying is that when Windows was rolled out to the world as an application development platform, the associated C development environment enforced function signatures pretty strictly. Things are really not much improved for the Windows API programmer of today. The tools are better, but the API itself and the languages associated with it use fundamentally similar declarations and mechanisms.

                                  jschell wrote:

                                  So in terms of prototyping the the pinvoke method itself - the developer should choose a name that most closely mimics that of the documentation for the method itself. Regardless of what that name is.

                                  It will usually end up being Hungarian if your guideline is followed.

                                  jschell wrote:

                                  Nope. Not as parameters into the wrapper itself. It might need to use a IntPtr but in that case
                                  1. The wrapper should paass appropriate C#/.Net data types to the method.
                                  2. The method constructs a IntPtr using the passed in values as appropriate.

                                  Step 2 is where I might consider using Hungarian notation. Realize that "constructs an IntPtr" can end up equating to quite a lot of code, and multiple, associated IntPtrs might actually need to be created. If you can get by just calling these ip1, ip2, etc., or if you prefer calling them, say, nextWindowHandle instead of hNextWnd, then so be it. Regardless, you're facing the same issues Windows 1.0 application developers faced.

                                  J 1 Reply Last reply
                                  0
                                  • _ _beauw_

                                    jschell wrote:

                                    Which doesn't alter the fact that the use was entirely optional. So if you didn't include the header your code still worked - if you got the call correct.

                                    That seems like a very odd (and uncommon) way to write code. I can't imagine too many people did that.

                                    jschell wrote:

                                    Simonyi joined Microsoft in 1981. Simonyi came up with the idea before joining Microsoft.
                                     
                                    Are you claiming that prototypes were widely available before 1981 and Simonyi developed hungarian notation despite that?

                                    No, I don't think prototypes were common in C before 1981. And I am sure that Simonyi's variable-naming style (which is all this really is) evolved over his entire career. What I am saying is that when Windows was rolled out to the world as an application development platform, the associated C development environment enforced function signatures pretty strictly. Things are really not much improved for the Windows API programmer of today. The tools are better, but the API itself and the languages associated with it use fundamentally similar declarations and mechanisms.

                                    jschell wrote:

                                    So in terms of prototyping the the pinvoke method itself - the developer should choose a name that most closely mimics that of the documentation for the method itself. Regardless of what that name is.

                                    It will usually end up being Hungarian if your guideline is followed.

                                    jschell wrote:

                                    Nope. Not as parameters into the wrapper itself. It might need to use a IntPtr but in that case
                                    1. The wrapper should paass appropriate C#/.Net data types to the method.
                                    2. The method constructs a IntPtr using the passed in values as appropriate.

                                    Step 2 is where I might consider using Hungarian notation. Realize that "constructs an IntPtr" can end up equating to quite a lot of code, and multiple, associated IntPtrs might actually need to be created. If you can get by just calling these ip1, ip2, etc., or if you prefer calling them, say, nextWindowHandle instead of hNextWnd, then so be it. Regardless, you're facing the same issues Windows 1.0 application developers faced.

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

                                    _beauw_ wrote:

                                    That seems like a very odd (and uncommon) way to write code. I can't imagine too many people did that.

                                    Quite easy for me to think that people forgot to include them. Quite easy for me to think that, because they were optional, that some developers would consider them unnecessary and thus intentionally leave them out.

                                    _beauw_ wrote:

                                    And I am sure that Simonyi's variable-naming style (which is all this really is) evolved over his entire career.

                                    Which is regardless of the point that it originated before he joined Microsoft and also that the original popularzation occurred very early. "He developed the Hungarian notation convention[11] for naming variables. These standards were originally part of his doctoral thesis." "He received his Ph.D. in computer science from Stanford in 1977 with a dissertation on a software project management..."

                                    _beauw_ wrote:

                                    Regardless, you're facing the same issues Windows 1.0 application developers faced.

                                    I just re-read the entire thread. Again what I said was that if you need to use a C API method then you wrap it. If there is any exposure from that point then parameters that are passed are NOT interop types but are in instead .Net types. Requirements vary but pinvoke method usage is often simple and thus the only need for those types is to expose the functionality the rest of the .Net application via an API that takes C# native types. So there are no IntPtrs. If more complexity in the API into the functional layer is required then it should definitely represent .Net native types because the layer API should not be a direct map to the C API (otherwise it would be a simple mapping or require additional mapping.) Your statements however appear to be about local scope usage only. Again if it was me I would probably mimic the parameter names that appear ni the C API. And that has nothing to do with the hungarian notation that the names might or might not have but is instead based on the documented name any nothing else. Why someone else chose that name is irrelevant to why I use it.

                                    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