C++ Identifiers

This blog post will teach you about C++ Identifiers and their naming rules. I will try to explain the identifier in C++ with an example code. After reading this blog post, I believe you will be able to identify invalid and valid identifiers in C++.

What is an identifier in C++?

An identifier is a sequence of characters that is used to denote one of the following:

  • Class, structure, or union name.
  • Function or class-member function.
  • Member of a class, structure, union, or enumeration.
  • Object or variable name.
  • Enumerated type name.
  • typedef name.
  • Macro name.
  • Macro parameter.
  • Label name.

In C++, a valid identifier must start with a non-digit character (Latin letter, underscore, or Unicode character of class XID_Start) and continue with non-digit characters, digits, and elements of the translation character set of class XID_Continue.

The following characters are non-digit characters:

a b c d e f g h i j k l m
n o p q r s t u v w x y z
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z _

 

The following are the digits:

0 1 2 3 4 5 6 7 8 9

 

Note: Identifiers are case-sensitive, meaning identifiers “data” and “Data” are different.

 

Now let’s see some rules for naming identifiers with the help of example code.

Rules for naming identifiers in C++:

1. The first character of an identifier name must be a non-digit (including the underscore _, the lowercase and uppercase Latin letters, and other characters).

int 2data; //Invalid

float 9test; // Invalid

int data2; //Valid

int te9st; //Valid

 

2. A valid identifier must start with a non-digit character (Latin letter, underscore, or Unicode character of class XID_Start) and continue with non-digit characters, digits, and elements of the translation character set of class XID_Continue.

Example,

int data; //valid

int dat2a; //valid

int _data; //valid

int _Da2ta; //valid

 

 3. The reserved words (keywords) can not use as an identifier in C++ programming.

Example,

int for;  //invalid

float if;   //invalid

int goto;   //invalid

 

In C++, few identifiers have a special meaning when appearing in a certain context. These identifiers are final, import, module (since C++20), and override.

 

Another important point you should remember is that some identifiers are reserved for use by C++ implementations and you should not use them. They have the following forms.

  1. Each identifier that contains a double underscore( __ ) or begins with an underscores followed by an uppercase letter is reserved for the implementation of any use.
  2. Each identifier that begins with an underscore ( _ ) is reserved for the implementation for use as a name in the global namespace.

 

Naming Conventions in C++:

The C++ core guidelines have many naming and layout rules. Some of them are popular and some of them may be controversial.

In this blog post, I will not write about the naming and layout rules of the C++ core guidelines. But I will explain some rules which I am following personally in my own code.

In my opinion, your naming convention must be consistent throughout the project and everybody in the project must follow it.

So let’s see the name convention which I follow for my C++ code.

Class:

I follow the “Pascal Case” for the classes. The Pascal case is similar to the Camel case. The first letter of every word in the identifier starts with uppercase.

Here are some examples of how you would use the pascal case for your class.

class AticleWorld
{
    /*
    class member
    */

}


class SalaryCalculator
{
    /*
    class member
    */

}

 

The only difference between the pascal and camel cases is that the pascal case requires the first letter of the first word to also be capitalized.

 

class member variables:

I follow the camel case for the class member variables. I also use the prefix m_  followed p, pf or r if the member is a pointer, a pointer to a function, or a reference respectively.

Consider the below example,

class TestClass
{
public:
    int m_invalidData; //integer value

    int * m_pData; //pointer

    int & m_rData; //reference
};

 

class member methods:

I follow the camel case for the class member variables. See the below example,

class TestClass
{
public:
    void resetValue();
    
    bool setValue();
    
    bool readValue();
    
};

 

Interfaces:

I follow the pascal case for the C++ interfaces class. I also use the Iprefix with the interface class name. See the below example,

//Interface class
class ISalaryCalculator 
{
public:
    virtual monthlySalary() = 0;
    
    virtual singleDaySalary() = 0;
    
    virtual yearlySalary() = 0;

}

 

structs:

Similar to the class, I use the pascal case with structure also. Here is an example of how you would use the pascal case for your struct.

struct TestStruct
{

 // members

    
};

 

structs member variable:

I follow the camel case for the struct member variables. I use the prefix p, pf or r if the member is a pointer, a pointer to a function, or a reference respectively. See the below example,

struct TestStruct
{
public:
    int invalidData; //integer value
    
    int * pData; //pointer
    
    int & rData; //reference
};

 

Functions:

I follow the camel case for the functions. See the below example,

bool readTempValue()
{

 //code
    
}

bool writeTempValue()
{

 //code
    
}

 

Variable:

I follow the camel case for the variable. I also use the prefix p, pf or r if the variable is a pointer, a pointer to a function, or a reference respectively. See the below example,

//naming using the camel case

int lengthReadData; //int variable

int *pLengthReadData; //pointer

int &rLengthReadData; //reference

 

Parameters of methods and functions:

HereI also use the camel case with a prefix p, pf or r if the variable is a pointer, a pointer to a function, or a reference respectively. See the below example,

bool foo1(int dataSize) 


bool foo2(int* pDataSize) // pointer 


bool foo3(int& rDataSize)  // reference

 

Enumerations:

I follow the “Pascal Case” for the enumerations. I also use the prefix E with the enumeration name. See the below example,

enum EYourEnum
{
    //code

};

 

Enumerations Items:

I follow the “camel Case” for the enumerations items. I use the prefix e with the enumeration item. See the below example,

enum EYourEnum
{
    eData1,
    eData2,
    eData3,  
};

 

Constants:

I use the upper case for the constant. See the below code.

//naming convention for constant

const int MAX_DATA_SIZE = 10;

 

Template parameters:

I use the upper case for the template parameter. See the below example,

//TYPE and SIZE are template parameter

template <typename TYPE, size_t SIZE>
class YourArray
{
public:
    explicit YourArray() : m_array() {}
    virtual ~YourArray() {}

    TYPE* array()
    {
        return m_array;
    }

    int arraySize() const
    {
        return SIZE;
    }

private:
    //array
    TYPE m_array[SIZE];
};

 

File names:

I use the pascal case for the file names. For example, TempCalculator.cpp.

 

Recommended Post