4

I realize that this can be a matter of preference, but I have noticed that variables names in a lot of code samples I've seen have a prefix of g_, s_, m_, or just _. Is this a commonly accepted practice, and what do these prefixes mean? Are there any others that would be good to know?

Jim Fell
  • 13,750
  • 36
  • 127
  • 202
  • It's interesting that the discussion has so far avoided the relative merits of `word_with_underscores` vs `LeadingCapsForWords` vs `camelCaseNames`. I know that is far more contentious - and the prefixes asked about tend to be used with `g_lower_case_words`. – Jonathan Leffler Dec 02 '10 at 17:39
  • Worth a read: http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797 – Martin York Dec 02 '10 at 18:53

5 Answers5

9
  • g_ is a global variable
  • s_ is a static
  • m_ is a member (an instance variable)
  • _ is either a member, or more specifically a private member (both usages turn up)

This is common enough that many developers know about it, although it is not (to my knowledge) universally accepted. I don't think you are missing any others.

Update: Integrating comments below for better visibility

  • _ can also be used to denote a local variable (this one really isn't "standard")
  • k can be used to denote a constant
Jon
  • 428,835
  • 81
  • 738
  • 806
  • +1 Excellent answer. For the sake of completeness, I'll note that I've also seen `_` indicate a *local* variable. – Cody Gray - on strike Dec 02 '10 at 15:44
  • k is also often used for constants. (Beats me why!) – Johan Kotlinski Dec 02 '10 at 15:48
  • AFAIK `kThingy` is an Apple (OpenStep/NextStep?) convention. – MSalters Dec 02 '10 at 15:51
  • 1
    I personally find it better to add _m/g/s as a suffix since it saves you typing when you use some sort of auto completion. – Palmik Dec 02 '10 at 15:52
  • These prefixes have hurt my autocompletion too whenever I used them (that's why I don't always use them), but as suffixes I find them simply hideous. – Jon Dec 02 '10 at 15:54
  • Just for further completeness, its called "Hungarian Notation" http://en.wikipedia.org/wiki/Hungarian_notation – pstrjds Dec 02 '10 at 16:14
  • @pstrjds: You are mistaken. Hungarian notation as a different thing entirely: the practice of prefixing variables as a function of their *type*. – Jon Dec 02 '10 at 16:28
  • @Jon: There are two primary variants of Hungarian notation, only one of which prefixes variables with their type. The other, arguably more useful variant, prefixes variables with their purpose or with an indicator of the data that they represent. Either way, the above would definitely count an extension of Hungarian naming. – Cody Gray - on strike Dec 02 '10 at 16:39
  • @Jon: I would certainly not call it "universally" accepted though, I only knew about "m_", "_" and "k" (with fixed meanings), and it is certainly not used everywhere I've poked at. – Matthieu M. Dec 02 '10 at 16:44
  • 1
    "k" for constants is fairly prevalent in mathematics and that usage probably comes from the German "konstant", that's probably how it got into the software world. – mu is too short Dec 02 '10 at 17:47
  • @Cody: I am aware of that, but I believe that's not the case here too. These prefixes are not about either the type or the logical purpose of a variable, but rather about its scope. But it's possible that the term is used in this sense also and I 'm simply unaware of it. – Jon Dec 02 '10 at 18:12
  • @Jon According to the wiki link I posted, it is an extension of Hungarian notation, although they point out that it is sometimes used even when not using Hungarian notation (although I have not come across that myself, apparently it is used without it). Quote: "The notation is sometimes extended in C++ to include the scope of a variable, separated by an underscore. This extension is often also used without the Hungarian type-specification:" – pstrjds Dec 03 '10 at 19:10
8

Beware the leading underscore; the C standard reserves names beginning with an underscore and various other combinations. ISO/IEC 9899:1999 (aka C99 standard) says:

§7.1.3 Reserved identifiers

Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

— All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

— Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).

— All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.154)

— Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

154) The list of reserved identifiers with external linkage includes errno, math_errhandling, setjmp, and va_end.

The rules are complicated enough that it is simpler to go with:

  • Do not start identifiers with an underscore

POSIX Reserved Identifier Conventions

Also beware of using the '_t' suffix for type names, especially in a POSIX environment. Actually, the rules on the linked page are more extensive than the rules in the C99 standard, but one line says "ANY HEADER suffix '_t'". That means that if you include any POSIX header in a POSIX environment - remembering that <stdio.h> is a POSIX header as well as a standard C header - then you should not have any typedefs which end in _t such as:

C:

typedef struct data_t { ... } data_t;  // Usurping POSIX namespace

C++:

struct data_t { ... };  // Usurping POSIX namespace

There are many other 'reserved namespace' rules in POSIX - see the linked page. This is one that is commonly flouted (but it has periodically hurt the project I work on because it ignores this rule - I don't get to set all the rules, sadly).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Yes - while I have seen underscores used to indicate members, they are trailing, not leading. – Johan Kotlinski Dec 02 '10 at 15:50
  • @Jonathan Leffler: By `_t`, are you referring to something like `myVar_t` or `_tMyVar`? – Jim Fell Dec 02 '10 at 15:55
  • 1
    _t usually means "typedef". E.g. typedef struct { blah blah } my_struct_t; or typedef unsigned int my_time_type_t; – AlastairG Dec 02 '10 at 15:56
  • @Konrad: I 've seen them used like `typedef int int32_t` and `typedef unsigned short uint16_t`. Conditional compilation, making sure that there are integer types with specific sizes. – Jon Dec 02 '10 at 15:56
  • Suffix means at the end so MyVar_t. This is because there are types like size_t or time_t. On POSIX systems most of the system specific types are something_t. – stonemetal Dec 02 '10 at 15:58
  • @Jon, @Alastair: I know what it means. I was wondering why one should beware – these identifiers are, to the best of my knowledge, **not** reserved. – Konrad Rudolph Dec 02 '10 at 16:00
  • 2
    `_t` is reserved by POSIX and should not be used in user code, but many people ignore this. – R.. GitHub STOP HELPING ICE Dec 02 '10 at 16:43
0

People sometimes use "g_" where they actually mean "f_", i.e. a file scope variable.

AlastairG
  • 4,119
  • 5
  • 26
  • 41
  • Wouldn't that be an `s_` for static? Static variables can only be used within a file. If a variable is simply declared without the `static` modifier it could be declared as `extern` in another module and linked. I've run into this problem when working on projects with multiple developers. Someone thinks they're being smart by implementing this hack when in reality they have no control over how the variable is maintained and it causes problems in the long run. – Jim Fell Dec 02 '10 at 15:58
  • A static variable can be limited to a function. `f_` explicitly means file scope - we use it here at work. – AlastairG Dec 02 '10 at 15:59
  • By file scope, are you referring to anonymous namespaces? – Marcin Dec 02 '10 at 16:17
  • I don't know what you mean by anonymous namespace, but I guess it could mean the same thing. By file scope I mean it only exists within the scope of that file. Technically only the part of the file after it is declared. – AlastairG Dec 02 '10 at 16:30
0

Aside from a lone underscore prefix (e.g. _foo) this is just very ugly style. Using the lone underscore usually results in undefined behavior.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
0

I personally find this practice totally unnecessary and in certain ways abhorrent. If you are using a decent IDE, you should not need any of this.

Jarek Przygódzki
  • 4,284
  • 2
  • 31
  • 41