202

What are the naming conventions commonly use in C? I know there are at least two:

  1. GNU / linux / K&R with lower_case_functions
  2. ? name ? with UpperCaseFoo functions

I am talking about C only here. Most of our projects are small embedded systems in which we use C.

Here is the one I am planning on using for my next project:


C Naming Convention

Struct              TitleCase
Struct Members      lower_case or lowerCase

Enum                ETitleCase
Enum Members        ALL_CAPS or lowerCase

Public functions    pfx_TitleCase (pfx = two or three letter module prefix)
Private functions   TitleCase
Trivial variables   i,x,n,f etc...
Local variables     lower_case or lowerCase
Global variables    g_lowerCase or g_lower_case (searchable by g_ prefix)
Solomon Ucko
  • 5,724
  • 3
  • 24
  • 45
JeffV
  • 52,985
  • 32
  • 103
  • 124
  • 13
    I wouldn't force a 'g_' prefix on global variables; I would enforce meaningful names (so client_locale and not cl_lc as a global variable name). Classic C doesn't use camel-case; I've written code in camel-case in C, and it looks weird (so I don't do it like that any more). That said, it isn't wrong - and consistency is more important than which convention is used. Avoid typedefs that encapsulate structure pointers; consider the C standard - 'FILE *' is spelled thus, not FILE_PTR. – Jonathan Leffler Nov 12 '09 at 13:34
  • 5
    @Jonathan Leffler, whats wrong with g_ to signify globals? In embedded systems I have had trouble before in which it was hard to track down inter-module dependencies through global vars and extern g_somevar. I personally think it is generally a bad idea, but this sort of thing usually gets done for performance reasons. For instance, a global flag that is set by an interrupt indicating that the data is ready. – JeffV Nov 12 '09 at 13:47
  • 2
    For what it's worth, this naming convention was mostly ripped from PalmOS API conventions. Also, it is similar to the convention used in O'Reilly's book: "Programming Embedded Systems with C and GNU Development Tools". Personally, I like the TitleCase in function names. I was thinking of going with lowerCamelCase in internal linkage functions (which I called private in my question). – JeffV Nov 12 '09 at 14:57
  • @Jeff V - The snarky answer is "keep track of global variables by noting that they haven't been defined as local variables in the function body," but I think there's some merit in this answer. If you have so many local variables that you can't tell which variables are local and which are global, your function is probably too big, and unless you have a good reason not to (space/memory/efficiency concerns), you should break it up. – Chris Lutz Nov 12 '09 at 23:07
  • 3
    @Chris Lutz, I agree, whole heartedly. Wherever possible vars are to be kept at the narrowest scope. Note that there are actually three scopes we are discussing: local to a function, local to a module (no externs linkage to the variable) and the globals with external linkage. It is common to have "global to a module" variables in embedded systems. Therefore, care must be taken to identify the globals with external linkage so they can be kept to a minimum and the module interactions understood. This is where the "g_" prefix is helpful. – JeffV Nov 13 '09 at 00:23
  • I agree with using some of the g_ notation. It's helpful in knowing whether something being referred to is global or somewhere else. – Gustavo Litovsky Jan 01 '13 at 23:07

13 Answers13

192

The most important thing here is consistency. That said, I follow the GTK+ coding convention, which can be summarized as follows:

  1. All macros and constants in caps: MAX_BUFFER_SIZE, TRACKING_ID_PREFIX.
  2. Struct names and typedef's in camelcase: GtkWidget, TrackingOrder.
  3. Functions that operate on structs: classic C style: gtk_widget_show(), tracking_order_process().
  4. Pointers: nothing fancy here: GtkWidget *foo, TrackingOrder *bar.
  5. Global variables: just don't use global variables. They are evil.
  6. Functions that are there, but shouldn't be called directly, or have obscure uses, or whatever: one or more underscores at the beginning: _refrobnicate_data_tables(), _destroy_cache().
axel_c
  • 6,557
  • 2
  • 28
  • 41
  • 27
    In point six I prefer to use `static` and skip the module prefix, so if `gtk_widget_show()` was a function with file scope it would become simply `widget_show()` with static storage class added. – August Karlstrom Aug 15 '13 at 14:28
  • 38
    Additional note about point 6: the C standard has some rules about reserving names that begin with `_` for implementation and future use. There are a few exceptions to names beginning with `_` but in my opinion it is not worth the trouble to memorize. A safe rule to go by is to never use names beginning with `_` in your code. Relevant C FAQ entry: http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=decl#namespace – jw013 Mar 21 '14 at 21:08
  • 2
    for point six, what about using trailing underscore? or a prefix such as "internal_"? – dragonxlwang May 04 '16 at 05:28
  • 14
    #2 is more specifically *upper camel case* or *pascal case*. Camel case or lower camel case uses lower case on the first letter. – Clint Pachl Nov 01 '17 at 05:44
  • 14
    What about local multi-word variables? my_var or myVar? – Dean Gurvitz Aug 09 '18 at 07:24
  • Haha "Global variables: just don't use global variables. They are evil." That was funny. Nice point though. – victory Mar 21 '19 at 22:20
  • 27
    `Global variables: just don't use global variables. They are evil.` - unless you are working on embedded project and you have 1024 bytes of RAM and 8MHz CPU. – Kamil Apr 23 '19 at 15:38
  • Yes @Kamil, that can be painful. But even in that case, it is a good practice to create a `static` global struct variable with all the global context, create a pointer as local variable in the main function and pass that pointer only to the functions that need to access the global data. – Hugo Cunha Jan 21 '21 at 14:56
45

You know, I like to keep it simple, but clear... So here's what I use, in C:

  • Trivial Variables: i,n,c,etc... (Only one letter. If one letter isn't clear, then make it a Local Variable)
  • Local Variables: camelCase
  • Global Variables: g_camelCase
  • Const Variables: ALL_CAPS
  • Pointer Variables: add a p_ to the prefix. For global variables it would be gp_var, for local variables p_var, for const variables p_VAR. If far pointers are used then use an fp_ instead of p_.
  • Structs: ModulePascalCase (Module = full module name, or a 2-3 letter abbreviation, but still in PascalCase.)
  • Struct Member Variables: camelCase
  • Enums: ModulePascalCase
  • Enum Values: ALL_CAPS
  • Public Functions: ModulePascalCase
  • Private Functions: PascalCase
  • Macros: PascalCase

I typedef my structs, but use the same name for both the tag and the typedef. The tag is not meant to be commonly used. Instead it's preferrable to use the typedef. I also forward declare the typedef in the public module header for encapsulation and so that I can use the typedef'd name in the definition.

Full struct Example:

typedef struct UtilsExampleStruct UtilsExampleStruct;
struct UtilsExampleStruct{
    int var;
    UtilsExampleStruct *p_link;
};
Sprite
  • 3,222
  • 1
  • 12
  • 29
SeanRamey
  • 665
  • 7
  • 19
  • 1
    I don't know anything about the qt framework, but you can write your code in whatever style format you want. Nothing is keeping you from it, as far as I know. – SeanRamey Aug 12 '18 at 01:11
  • 3
    Isn't it `PascalCase` and `camelCase`? – Michael Oct 20 '20 at 12:50
  • 2
    This format is similar to java and c# naming conventions. I'd simply suggest you to use camelCase for function naming and a module prefix for that such as ```MDL_functionName()``` and also i don't see the benefit of using p_ prefix for the pointers, i would remove it as well. – Osman Apr 11 '22 at 09:47
39

"Struct pointers" aren't entities that need a naming convention clause to cover them. They're just struct WhatEver *. DON'T hide the fact that there is a pointer involved with a clever and "obvious" typedef. It serves no purpose, is longer to type, and destroys the balance between declaration and access.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 40
    +1 for the "don't hide pointers" stuff - even though this answer doesn't address much of the rest of the question (yet). – Jonathan Leffler Nov 12 '09 at 13:35
  • 3
    @unwind, I tend to agree. However, sometimes a pointer is not intended to be external dereferenced and it is more of a handle to the consumer than an actual pointer to a struct they will be using. Thats what I left the TitleCasePtr for. typedef struct { fields } MyStruct, *MyStructPtr; – JeffV Nov 12 '09 at 13:35
  • I am removing the TitleCasePtr, it is distracting from the actual question. – JeffV Nov 12 '09 at 13:40
  • 1
    -1 from me since a pointer type declaration reduces clutter, especially in function signatures and the "imbalance" between declaration and access only shows up in the implementation file - the client don't (shouldn't) access the field members directly. – August Karlstrom Aug 15 '13 at 14:47
  • 1
    @AugustKarlstrom Fine. I don't understand what's so "only" about the implementation file though, isn't that code, too? I didn't interpret the question as only being about "external" names. All code is "implementation" at some level. – unwind Aug 15 '13 at 14:59
  • @unwind OK, use `struc WhatEver *` in the implementation file then. – August Karlstrom Aug 15 '13 at 15:23
  • Apple's Core Foundation framework is notorious for hiding pointers under typedefs, but based on my experience with it, these types are consistently suffixed with `Ref`, e.g. `CFStringRef`, `CFArrayRef` etc. – dreamlax Jun 01 '16 at 02:25
  • Hiding pointers using a typedef in order to create an incomplete type for the purpose of an interface where you don't want to the consumer accessing the underlying struct is elegant and clean style. For a good example, see the ADT pattern ([PART 1](http://adampetersen.se/Patterns%20in%20C%201.pdf)) in the *Patterns in C* series by Adam Thornhill/Petersen. – Clint Pachl Nov 01 '17 at 05:56
20

Well firstly C doesn't have public/private/virtual functions. That's C++ and it has different conventions. In C typically you have:

  • Constants in ALL_CAPS
  • Underscores to delimit words in structs or function names, hardly ever do you see camel case in C;
  • structs, typedefs, unions, members (of unions and structs) and enum values typically are in lower case (in my experience) rather than the C++/Java/C#/etc convention of making the first letter a capital but I guess it's possible in C too.

C++ is more complex. I've seen a real mix here. Camel case for class names or lowercase+underscores (camel case is more common in my experience). Structs are used rarely (and typically because a library requires them, otherwise you'd use classes).

cletus
  • 616,129
  • 168
  • 910
  • 942
  • @cletus, I realize that. By private I mean functions that are not exposed externally in the module header and are not intended to be used by code external to the module. Public would be module API functions intended to be used externally. – JeffV Nov 12 '09 at 13:28
  • 3
    You could regard static functions as private; the question doesn't mention virtual. But +1 for 'seldom see camel-case in C'. – Jonathan Leffler Nov 12 '09 at 13:30
  • 3
    I think Jeff meant `external linkage` for "public functions" and `internal linkage` for "private functions". – pmg Nov 12 '09 at 13:30
  • 1
    I've seen constants starting with a k as well as in: kBufferSize. Not sure where that comes from. – JeffV Nov 12 '09 at 14:14
  • cletus is referring to #define constants. They should always be ALL_CAPS. – jmucchiello Nov 12 '09 at 16:47
  • Like I said, I've seen the use of kTitleCase style with defined constants. I preffer ALL_CAPS too, though. – JeffV Nov 12 '09 at 22:13
  • 2
    `ALL_CAPS` is often used for enum values, too. – caf Nov 13 '09 at 01:15
  • Apple's Core Foundation and Microsoft's Win32 are two major C APIs that use camel case. I'm sure there are others, but I regularly write programs using both of those, so anecdotally I'd have to disagree that you seldom see camel case in C. – dreamlax Jun 01 '16 at 02:26
12

Coding in C#, java, C, C++ and objective C at the same time, I've adopted a very simple and clear naming convention to simplify my life.

First of all, it relies on the power of modern IDEs (such as eclipse, Xcode...), with the possibility to get fast information by hovering or ctrl click... Accepting that, I suppressed the use of any prefix, suffix and other markers that are simply given by the IDE.

Then, the convention:

  • Any names MUST be a readable sentence explaining what you have. Like "this is my convention".
  • Then, 4 methods to get a convention out of a sentence:
    1. THIS_IS_MY_CONVENTION for macros, enum members
    2. ThisIsMyConvention for file name, object name (class, struct, enum, union...), function name, method name, typedef
    3. this_is_my_convention global and local variables,
      parameters, struct and union elements
    4. thisismyconvention [optional] very local and temporary variables (such like a for() loop index)

And that's it.

It gives

class MyClass {
    enum TheEnumeration {
        FIRST_ELEMENT,
        SECOND_ELEMENT,
    }

    int class_variable;

    int MyMethod(int first_param, int second_parameter) {
        int local_variable;
        TheEnumeration local_enum;
        for(int myindex=0, myindex<class_variable, myindex++) {
             localEnum = FIRST_ELEMENT;
        }
    }
}
Luc Fourestier
  • 129
  • 1
  • 3
10

Here's an (apparently) uncommon one, which I've found useful: module name in CamelCase, then an underscore, then function or file-scope name in CamelCase. So for example:

Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]
Steve Melnikoff
  • 2,620
  • 1
  • 22
  • 24
9

I would recommend against mixing camel case and underscore separation (like you proposed for struct members). This is confusing. You'd think, hey I have get_length so I should probably have make_subset and then you find out it's actually makeSubset. Use the principle of least astonishment, and be consistent.

I do find CamelCase useful to type names, like structs, typedefs and enums. That's about all, though. For all the rest (function names, struct member names, etc.) I use underscore_separation.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
  • 1
    Yes, the main thing about any naming convention is predictability and consistency. Also, because the C library itself using all lowercase with _ for spacing, I would recommend using that just so you don't have to deal with 2 different naming conventions in a project(assuming you don't write a wrapper around libc to make it conform to your naming.. but thats gross) – Earlz Nov 12 '09 at 14:14
  • It also uses typedefs with an "_t" on the end, but I don't see anyone recommending that. In fact, the standard library is even inconsistent: div_t (stdlib.h) is a struct and so is tm (time.h). Also, take a look at the tm struct members, they all are prefixed with tm_ which seems pointless and ugly (IMO). – JeffV Nov 12 '09 at 14:27
  • 1
    "I do find CamelCase useful to type names..." If you start it off capitalised, it's actually PascalCase. – Tagc Dec 15 '16 at 13:37
  • Writting macros all in uppercase to me sounds like constants, as even the C reserved has lowercase macros. But with function-like macros you can pass type and do other strange things. In this case, I'm prefixing with a shortened camelCase name of the library followed by underline and the name function with a lengthy parameter name to serve as documentation/disambiguation (using ide auto completing). For every library externalized function I'm prefixing with the all-lowercase shortened name of the library and for static functions giving free lowercase and underscore names. – Arkt8 Nov 13 '22 at 19:35
6

You should also think about the order of the words to make the auto name completion easier.

A good practice: library name + module name + action + subject

If a part is not relevant just skip it, but at least a module name and an action always should be presented.

Examples:

  • function name: os_task_set_prio, list_get_size, avg_get
  • define (here usually no action part): OS_TASK_PRIO_MAX
4

When I will program in C I will use this convention:

definitions prefix examples
variables - local (trivial) / i, n, a, b...
ii, nn, aa, bb...
iii, nnn, aaa, bbb...
variable - local (descriptive) / variable, conection...
variable - global g_ g_variable, g_connection...
variable - constant c_ c_variable, c_connection...
pointer p_ p_variable , p_connection...
array a_ a_variable, a_connection...
struct s_ s_variable, s_connection...
union u_ u_variable, u_connection...
enum e_ e_variables, e_connection...
struct (member)
union (member)
enum (member)
m_
m_
m_
m_variable, m_connection...
m_variable, m_connection...
m_variable, m_connection...
struct (bit field) b_ b_variable, b_connection...
function f_ f_variable, f_connection...
macro o_ o_variable, o_connection...

Note:

Each definition except variables has a single letter prefix, so that they can be combined and then not being miss understood.

Note:

Because I ran out of letters and I insisted to have only lower case letter prefixes, prefix "o_" used for macro does not match the first letter of the definition (macro) but it matches the last letter (macro).

If you have any suggestions I am open minded.

71GA
  • 1,132
  • 6
  • 36
  • 69
  • 2
    This is very clean – drudru Mar 15 '21 at 18:04
  • But not the best. It is much better to never use long local variable names *(except for global variables so that it is harder to avoid multiple definitions)*... I rather use one letter local variable names as `c` which I always define at the top of the function. This is one of the two cases where I add line comments e.g. `c // Connection`, `b // Byte`, `t // Temporary work buffer`... All of my code is now much easier to read! My philosophy is that code needs to be formated in logical paragraphs! Just like normal text! On top of complex comments is where I also put a simple line comment... – 71GA Apr 23 '21 at 16:53
  • ... This comment looks like a label e.g. `// A:`, `// B:`, `// C:`... I am working in `vim`/`nvim` so when I get to the paragraph that I don't understand, I hoover over this comment / label and press a key combination **ALTGR** + **3** (`^`) so that I get the *previous* location of this same label and this is at the top of the function where I have a paragraph explanations prefixed by `// A:`, `// B:`, `// C:`.... as well. This works flawlessly! I use multiline comments only to comment out the code and not for comments or function explanations! If I have to comment a single line I use `///`. – 71GA Apr 23 '21 at 16:59
  • So code remains compact and all the explanations are gathered at the top of the function and are easiliy accessible by only using a key combination! – 71GA Apr 23 '21 at 17:03
3

I'm confused by one thing: You're planning to create a new naming convention for a new project. Generally you should have a naming convention that is company- or team-wide. If you already have projects that have any form of naming convention, you should not change the convention for a new project. If the convention above is just codification of your existing practices, then you are golden. The more it differs from existing de facto standards the harder it will be to gain mindshare in the new standard.

About the only suggestion I would add is I've taken a liking to _t at the end of types in the style of uint32_t and size_t. It's very C-ish to me although some might complain it's just "reverse" Hungarian.

jmucchiello
  • 18,754
  • 7
  • 41
  • 61
  • 4
    Well, the conventions here are all over the place and inconsistent which is why I am setting out to document one. Also, it is why I am asking. To see what the community consensus is. – JeffV Nov 12 '09 at 14:31
  • I understand that pain. But there must be some subset of your existing conventions that is most popular. You should start there and not on a random Internet web page. Also you should ask your other devs what they would consider good. – jmucchiello Nov 12 '09 at 16:46
  • 7
    I believe type names ending in _t are reserved by the POSIX standard. – caf Nov 13 '09 at 01:18
  • 4
    Name finishing with _t are reserved. See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html, "Names that end with ‘_t’ are reserved for additional type names. " – Étienne Aug 13 '13 at 19:53
2

There could be many, mainly IDEs dictate some trends and C++ conventions are also pushing. For C commonly:

  • UNDERSCORED_UPPER_CASE (macro definitions, constants, enum members)
  • underscored_lower_case (variables, functions)
  • CamelCase (custom types: structs, enums, unions)
  • uncappedCamelCase (oppa Java style)
  • UnderScored_CamelCase (variables, functions under kind of namespaces)

Hungarian notation for globals are fine but not for types. And even for trivial names, please use at least two characters.

renonsz
  • 571
  • 1
  • 4
  • 17
2

I recommend you to read this document.

Abstract
This document is an updated version of the Indian Hill C Style and Coding Standards paper, with modifications by the last three authors. It describes a recommended coding standard for C programs. The scope is coding style, not functional organization.

user16217248
  • 3,119
  • 19
  • 19
  • 37
SimoX
  • 250
  • 6
  • 13
-3

I think those can help for beginner: Naming convention of variables in c

  1. You have to use Alphabetic Character (a-z, A-Z), Digit (0-9) and Under Score (_). It’s not allow to use any special Character like: %, $, #, @ etc. So, you can use user_name as variable but cannot use user&name.
  2. Can not use white space between words. So, you can use user_name or username or username as variable but cannot use user name.
  3. Can not start naming with digit. So, you can use user1 or user2 as variable but cannot use 1user.
  4. It is case sensitive language. Uppercase and lowercase are significant. If you use a variable like username then you cannot use USERNAME or Username for father use.
  5. You can not use any keyword (char, int, if, for, while etc) for variable declaration.
  6. ANSI standard recognizes a length of 31 characters for a variable name
Amranur Rahman
  • 1,061
  • 17
  • 29
  • 7
    This post clearly aims to discuss naming **conventions**, not **restrictions**. What you listed are things you *cannot* even do because those are syntax errors. – Chase Feb 08 '20 at 17:08
  • 1
    It would be good to delete this answer, googling "enum naming convention c" previews this part of the question. – Random Aug 30 '22 at 12:01