开发者

Technical reasons for names containing underscores?

Are there any technical reasons for the use of the underscore in names like (for example)开发者_JAVA百科 scoped_lock in the Boost library? Why not call it `ScopedLock?

Please note I am not asking about stylistic reasons.


From the Boost Library Requirements and Guidelines,

Given the intent to propose portions of boost for the next revision of the C++ standard library, boost decided to follow the standard library's conventions.


There is no technical reason. If you ignore the stylistic reason, you could write scopedlock, istreamiterator and the-like too.


Readability if you can call that technical... spaces are usually forbidden and underscore is the nearest match. Camel case is horrible to read (an often is reserved for classes as a convention)..


Underscores improve the interface with human neural hardware by creating more space between separate words.

I used to prefer camelcase when I was little, and had a small monitor and small hands. I've mostly come around, though.


Subjectively I find underscores a bit of overkill in code. There is enough abuse of non-alphanumeric symbols in code as is, I think introducing them into identifiers is a bit over the top. Just off the top of my head consider this excerpt from a boost template error:

Derived=boost::transform_iterator<std::binder1st<std::multiplies<size_t>>,boost::counting_iterator<size_t>>,
Base=boost::counting_iterator<size_t>,
Value=boost::detail::transform_iterator_base<std::binder1st<std::multiplies<size_t>>,boost::counting_iterator<size_t>,boost::use_default,boost::use_default>::cv_value_type,
Traversal=boost::use_default,
Reference=boost::detail::transform_iterator_base<std::binder1st<std::multiplies<size_t>>,boost::counting_iterator<size_t>,boost::use_default,boost::use_default>::reference,
Difference=boost::use_default

versus the following that has been converted to Pascal case (I prefer this method):

Derived=boost::TransformIterator<std::Binder1st<std::Multiplies<SizeT>>,boost::CountingIterator<SizeT>>,
Base=boost::CountingIterator<SizeT>,
Value=boost::detail::TransformIteratorBase<std::Binder1st<std::Multiplies<SizeT>>,boost::CountingIterator<SizeT>,boost::UseDefault,boost::UseDefault>::CVValueType,
Traversal=boost::UseDefault,
Reference=boost::detail::TransformIteratorBase<std::Binder1st<std::Multiplies<SizeT>>,boost::CountingIterator<SizeT>,boost::UseDefault,boost::UseDefault>::Reference,
Difference=boost::UseDefault

I can see the advantage of underscores when taken in isolation but with all our other symbols I think we should focus on making programs that read closer to english and not underscore-ese.


There's no technical reason, but there's a reason. You've got to agree with me that it's much easier to read scoped_lock then scopedlock, but scopedLock would make it too. Yet, with underscore is easier to read, IMHO.

But a well-written code is a legible code. It's part of knowing to program well.


There's no technical reason.

Variable names in C++ must only

  • Start with a letter or underscore
  • Contain only number, letters (capitalized or not) and underscores

Using this_way or ThisWay is just a matter of style.


The only technical reason is for readability because using CamelCase may cause the wrong interpretation, especially when referring to abbreviations in all caps. A GPS Socket would come out as GPSSocket. There are some better examples, but my mental block precludes me from writing them down. :-(

If you want to get technical, there is no reason since the underscore is a viable character for identifiers.


Although technically speaking there is no difference there could be issues caused by environment. For instance, if you include windows.h you will not want to name any function TextOut even if that's what the function does. The reason is that this name will get replaced by the preprocessor due to the fact that TextOut is a macro in the win32 API. For this reason a project manager may wish to impose non-camel case as a standard.

So there can be technical reasons but there's no reason imposed by the language itself. It's not like Java (does it still do this?) where you are forced by the compiler to use camel case.


There is no technical reason per se. But I do have a reason other than my glib "because they look kewl."

My reason is because I find it useful to distinguish member variables from non-member variables in a convenient way. In particular when I am transferring data from a local variable to a member variable, such as within a constructor. Cheap example:

class Socket
{
public:
  Socket(const sockaddr_in& group)
  :  group_(group)
  {
  }
private:
  sockaddr_in group_;
};

If you ask my opinion, most variable naming schemes are terrible because there are too many rules and too many ways they break down. The classic example of a horrible naming scheme is Hungarian, but even from that I did take something useful: the m_ prefix for member variables came in handy at times. Not too often but often enough for me to borrow the idea if not the method.


There is no technical reason. It is purely stylistic. To be specific, C++ views all symbols that begin with a letter, underscore, or dollar sign the same. The only difference is how they are declared. If you want, you can name your "thing" class as Thing, THING, thing, tHiNg, or even T_h_I_n_G_$ if you want... it won't make a difference to the compiler. However, it does make a difference to other human beings that will look at and use your code. And if you take this too far (such as the last couple of examples I listed), you might even find your life in danger at some point (an angry programmer can be a terrifying thing).


There is no technical reason for or against except that which is imposed by the language, which in this case, does not exist.


This reason skirts the edges of being stylistic, but since no one else has mentioned this so far, I'll simply add that in a case sensitive language like C++, underscores are more memorable than capitalization.

For example, sometimes you might see scopedLock instead of ScopedLock. If you never use caps, that's just one less thing to keep track of.


Well, not the compilers, but prefast rulesets sometimes try to enforce naming conventions. To be frank, so many conventions are really confusing; escpecially when one needs to support old code as well as write new code in multiple languages.


One technical reason I can think of (especially for member function names) is to allow duck-typing. For example, the following boost classes could be used (to some extent) where one expects an STL container:

  • boost::ptr_container and family
  • boost::multi_index containers
  • boost::array
  • boost::dynamic_bitset (in lieu of boost::bitset)


IMHO, it is pretty reasonable to adopt the style of the Standard Library for the language you use. If it is Java, it is scopedLock, if it is C++ it is scoped_lock. If it is Lisp, it is scoped-lock.

Not that it really matters, anyway.


When C was invented, it was used on Unix, and Unix was operated from terminals that resembled typewriters. Some terminals had both upper and lower case letters, but some terminals had only upper case. If you wanted to use a Unix system but all of the nice terminals were already occupied by your mean greedy selfish colleagues, you got stuck with an older terminal. This is the reason why, if you type your login name in all upper case characters, Unix assumes you don't have lower case. Each lower case letter gets displayed as the corresponding upper case letter, and each upper case letter gets displayed as an asterisk followed by itself.

Now imagine camel casing instead of underscores.

By the way C was based more or less loosely on PL/I. PL/I was punched into cards which originally didn't support lower case, and eventually could be hacked to support lower case but not in a puncher-friendly fashion. Furthermore it was usually printed by printers that didn't support lower case, though a few did. So lower case was out, camel case was out, and programmers were used to underscores. (Except for Cobol programmers, who were used to minus signs in the middle of identifiers meaning this-is-an-identifier not this minus is minus an minus identifier.)

Pascal was invented later, in an environment where lower case letters were more common but still not universal. Camel case became possible because Pascal was case insensitive. Camel case became popular because Pascal didn't allow underscores in identifiers.

So if you like camel case combined with case sensitivity, you're half-Pasced.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜