Why is the "_" character in front of most variable names?

This is a discussion on Why is the "_" character in front of most variable names? within the C++ Programming forums, part of the General Programming Boards category; Why is the "_" character in front of most variable names? Example: _SomeVar; _Str; I also notice: m_SomeVar; Is there ...

  1. #1
    0x01
    Join Date
    Sep 2001
    Posts
    88

    Why is the "_" character in front of most variable names?

    Why is the "_" character in front of most variable names?

    Example:

    _SomeVar;
    _Str;

    I also notice:

    m_SomeVar;


    Is there some rule to this?
    Should I do this?

    And why is "lp" placed at the beginning of every DWORD type in MSVC++?

    How come this type of "pre-fixing" isn't explained anywhere?

  2. #2
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    In classes, people often prefix variables with either m_ or _ to denote member variables. It is actually against good convention to put anything into the global namespace with _ or __ as a prefix -- these are reserved for compiler vendors only.

    lp means "long pointer", and it's used for something of type "long *". Hungarian notation is a good naming scheme (although some people despise it), but in any event don't overdo it.

  3. #3
    0x01
    Join Date
    Sep 2001
    Posts
    88
    I see.

    The reason I asked, was because I have a hard time figuring out what to name my variables within my classes; heres why.

    For example: Lets say I have the member "char *string" within my class... it will be private, and an accessor function will be used to retrieve it etc...

    This is where I sometimes have a problem:
    What am I going to name this "accessor function?" It can't be 'string', because that name has been taken... and I hate naming methods with 'Get', in this case it would be 'GetString()'... and If I wanted the method name to have the name 'string' then I would have to change the variable/member name to something like 'theString' or 'itsString' which I also hate doing.

    Does anyone have a better way?

  4. #4
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    Well, in general, I really think GetX() and SetX() are good ways for accessor functions. string is a bad name for anything, because it is a C++ classname. I usually have member variables prefixed with _ or m_.

    Actually, that's not technically true; I usually make a struct that stores all my member variables, and hide the implementation that way, something like this:

    Code:
    MyClass.h
    class CMyClass{
    public:
      /* Public interface */
    protected:
      /* Protected interface */
    private:
      /* Private helper functions */
      struct Impl;
      Impl * pImpl; // I usually actually use std::auto_ptr or boost::shared_ptr instead of a "naked pointer"
    };
    Code:
    MyClass.cpp
    
    struct CMyClass::Impl{
      /* The class members go here */
    };
    
    /* Functions defined here */
    This is the "PIMPL" idiom, and is widely used. It minimizes compile times (the entire implementation affects only one .CPP file) and it puts the entire interface in one file, the implementation details in another.

  5. #5
    0x01
    Join Date
    Sep 2001
    Posts
    88
    I didn't say I used 'string', that was just an example.
    Cat >> I usually have member variables prefixed with _ or m_.
    But... you just said
    Cat >> It is actually against good convention to put anything into the global namespace with _ or __ as a prefix -- these are reserved for compiler vendors only."
    It minimizes compile times (the entire implementation affects only one .CPP file) and it puts the entire interface in one file, the implementation details in another.
    I have read that line over and over again trying to think, why placing a 'struct' containing all the members you would originally have in your class would minimize compile time... If anything I would think that would increase compile time.... And splitting your class into 2 files is kind of awkward to me... because I would have to switch from file-to-file if I were to observe it... Maybe I don't understand what you just said.

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    The reason I asked, was because I have a hard time figuring out what to name my variables within my classes; heres why.

    For example: Lets say I have the member "char *string" within my class... it will be private, and an accessor function will be used to retrieve it etc...
    How about using a name that describes what the variable is? If the char* string is the name of a person, use char* name. If it's their address, use char* address.

    Function names should also be descriptive, and that is why accessor functions are usually named something like GetName(). It's short and descriptive. If you would rather use a name like GoIntoMyClassAndObtainTheMemberCalledName() feel free to do that. Some editors automatically complete variable names, so you won't even have to type the name more than once. If you hate all the typing with variable names in the first place, and you don't want other people to be able to read your code anyway so that you personally have to be rehired to update things, then use X, Y, and Z for names.

  7. #7
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244
    Usually I use the "cl" prefix to denote a class atribute.
    Then I use "f" to a function scope variable. I like to use "par" in long functions to not forget where I have the declaration of some variable.
    Nothing more to tell about me...
    Happy day =)

  8. #8
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    BTW, knave, I said never to put _ or __ in the global namespace -- it's OK to have members as that name, because they're within the namespace of that class. However, I think it is in fact better to never use _ or __ at the beginning, when thinking further, because although members in a class namespace will prevent a naming conflict, macros could be named with _ or __ and macros don't respect namespace boundaries.


    Originally posted by knave
    I have read that line over and over again trying to think, why placing a 'struct' containing all the members you would originally have in your class would minimize compile time... If anything I would think that would increase compile time.... And splitting your class into 2 files is kind of awkward to me... because I would have to switch from file-to-file if I were to observe it... Maybe I don't understand what you just said.
    It minimizes recompile time, because an implementation change affects only one file. If you #include the header in 30 files, and if you added a variable without using PIMPL, you'd recompile all 30. With PIMPL, you recompile only one, because the header doesn't change.

    It's always good to split into two, anyway, and splitting by interface (.h file) and implementation (.cpp) is a good way to go.

  9. #9
    *******argv[] - hu? darksaidin's Avatar
    Join Date
    Jul 2003
    Posts
    314
    I don't use a special prefix for class members. After all, thats what the classes' namespace is for.

    Cat's PIMPL (pointer to implementation?) seems to reduce the number of times your files need to be recompiled because of header changes, but it doesn't reduce the individual compile time if there is no change (? I think ?) .
    I can't speak for anybody else, but I wouldn't use this as it makes the code harder to read. For me, the only reason to sacrifice readability is runtime speed. But thats of couse just my opinion.

    Other than that I like to use capital letters at the beginning of type/clasnames only. A char array would be acSomeFakeString, a pointer pSomepointer, a class CSomeClass, a struct type TSomeStruct, a pointer to an object of a class poSomeObjPtr, an integer iMyInteger or a struct variable tStructVar.... ....

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    For me, the only reason to sacrifice readability is runtime speed.
    And PIMPL does exactly the opposite.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    Originally posted by darksaidin
    I don't use a special prefix for class members. After all, thats what the classes' namespace is for.

    Cat's PIMPL (pointer to implementation?) seems to reduce the number of times your files need to be recompiled because of header changes, but it doesn't reduce the individual compile time if there is no change (? I think ?) .
    If there is no change, the compile time should be zero, so it can't really change it.

    I can't speak for anybody else, but I wouldn't use this as it makes the code harder to read. For me, the only reason to sacrifice readability is runtime speed. But thats of couse just my opinion.
    Quite the opposite, it improves readability, and there is little if any runtime hit. It makes code more legible and it separates interface and implementation. It also makes the class more encapsulated because the details of the class are completely hidden from other compilation units.

  12. #12
    *******argv[] - hu? darksaidin's Avatar
    Join Date
    Jul 2003
    Posts
    314
    Originally posted by Cat
    If there is no change, the compile time should be zero, so it can't really change it.
    Oops, I wanted to say: ... if there is no change to the header *but* in the C that uses that header.

    Originally posted by Cat
    Quite the opposite, it improves readability, and there is little if any runtime hit. It makes code more legible and it separates interface and implementation. It also makes the class more encapsulated because the details of the class are completely hidden from other compilation units.
    It's probably just a question of personal preference - as with most things. (Did I mention interface and implementation are Delphi keywords? - units...) ...

    Anyway, after a second glance at the codesnipped, it doesn't really look that bad ...in the interface part. Don't even want to see the implementation with all those pImpl->someprivatefunc(..)

    What happens if you use this system in the classes public interface and compile it to a library? Will you be able to access anything in the pimpl stuct ? After all there is no definition for it in the header.

  13. #13
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    What happens if you use this system in the classes public interface and compile it to a library? Will you be able to access anything in the pimpl stuct ? After all there is no definition for it in the header?
    That's exactly the point. The entire interface (public & protected methods) are visible. Nothing outside of the class should ever touch any part of the implementation. They access the class internals only through the interface. They can't, and shouldn't, know how the interface is implemented.

    And yes, the methods which make up the interface can still access the pImpl structure, because they are defined within the same .cpp file as the Impl structure itself. You can compile it into a library, .obj, whatever, and the functions will work just fine. However, nothing outside of the class's .cpp will be able to directly use anything within pImpl (in those translation units, it's a pointer to an incomplete type) but that's what we want, anyway.

    As to compile time: I was referring to a single change to the implementation. In the non-PIMPL way, if you change how something is implemented, it can affect many .CPP files. For example, say I have this in a header:

    Code:
    class MemoryBlock{
    public:
      void * GetMemPtr();
      int GetMemSize() const;
    private:
      unsigned char buffer[256];
    };
    Now assume this header is widely used in a large project (say it's included in 30 different .CPP files, besides the one that MemoryBlock is implemented in). If I want to adjust the size of buffer to 1024, every single one of those 31 files needs to be recompiled. And the worst part is, only one of those files even needed to be aware of the change; to the 30 files that use MemoryBlocks, the variable buffer wasn't directly accessible anyway, why do they care if it changed?

    Using the PIMPL idiom, only one of those 31 files would be recompiled -- the implementation file. The files which use the class are unaffected by our implementation change.

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    Whatever else, it means that you cannot have inline functions that access the PIMPL struct.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    That depends on the compiler. Some compilers do allow functions that are defined in a .CPP file to be inlined; it's not (always) required that the function body be visible to all calling code.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Concatenating in linked list
    By drater in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 11:10 PM
  2. Int and Character in the same variable
    By A13W in forum C++ Programming
    Replies: 13
    Last Post: 02-10-2008, 07:05 PM
  3. Valid variable and function names
    By sean in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 06-29-2002, 12:30 PM
  4. variable names
    By trekker in forum C Programming
    Replies: 3
    Last Post: 03-16-2002, 02:37 AM
  5. Having problems incrementing variable names
    By Legolas in forum C++ Programming
    Replies: 4
    Last Post: 11-11-2001, 09:14 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21