riverrock
riverrock

Reputation: 107

why to use an underscore for a struct in c?

In the source code below, could somebody explain the rational (why is it good programming practice to typedef the struct _lwm2m_object_t with the new name lwm2m_object_t? All it does is drop the underscore? Why is an underscore used in the first instance?

typedef struct _lwm2m_object_t lwm2m_object_t;

typedef uint8_t (*lwm2m_read_callback_t) (lwm2m_uri_t * uriP, char ** bufferP, int * lengthP, lwm2m_object_t * objectP);
typedef uint8_t (*lwm2m_write_callback_t) (lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_object_t * objectP);
typedef uint8_t (*lwm2m_execute_callback_t) (lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_object_t * objectP);
typedef uint8_t (*lwm2m_create_callback_t) (lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_object_t * objectP);
typedef uint8_t (*lwm2m_delete_callback_t) (uint16_t id, lwm2m_object_t * objectP);
typedef void (*lwm2m_close_callback_t) (lwm2m_object_t * objectP);


struct _lwm2m_object_t
{
    uint16_t                 objID;
    lwm2m_list_t *           instanceList;
    lwm2m_read_callback_t    readFunc;
    lwm2m_write_callback_t   writeFunc;
    lwm2m_execute_callback_t executeFunc;
    lwm2m_create_callback_t  createFunc;
    lwm2m_delete_callback_t  deleteFunc;
    lwm2m_close_callback_t   closeFunc;
    void *                   userData;
};

Upvotes: 3

Views: 6759

Answers (4)

gsamaras
gsamaras

Reputation: 73444

[Edit 2024] Note though that GCC Reserved Names says:

Names that end with ‘_t’ are reserved for additional type names.

Identifiers ending with _t are also reserved under POSIX: ANY header _t


A leading underscore is used for different purposes by every person or team. Read more in this answer, specifically the paragraph that is dedicated to .

I usually see this:

typedef struct lwm2m_object lwm2m_object_t;

where one will append a _t to the struct's name, denoting to the reader that this is a typedef'ef name.

Upvotes: 3

John Bode
John Bode

Reputation: 123598

By itself, the leading underscore has no intrinsic meaning, it just creates a distinct identifier for the tag name vs. the typedef name. You could achieve the same result with

typedef struct foo fooType;

Tag names occupy a different namespace from ordinary identifiers, so you can write

typedef struct foo foo;

which some people consider confusing. I don't - the tag name is disambiguated by the presence of the struct (or union or enum) keyword.

You should not use leading underscores in your identifiers - identifiers with two leading underscores or a leading underscore followed by a capital letter are always reserved for the implementation for any use, while identifiers with a single leading underscore are reserved in the ordinary and tag name spaces.

You could use a trailing underscore for the same effect

typedef struct foo_ foo;

and satisfy everybody.

Upvotes: 1

Rishikesh Raje
Rishikesh Raje

Reputation: 8614

Actually if you use

typedef struct lwm2m_object_t lwm2m_object_t;

struct lwm2m_object_t {
//
}

It will still be allowed by C. This is because the structure names and the typedef identifiers have different namespaces. Please see Why doesn't ANSI C have namespaces? for information about namespaces in C.

However, many professional users avoid this and use different names for structures and typedefs. MISRA1 also disallows this.

Rule 5.6 (advisory): No identifier in one name space should have the same spelling as an identifier in another name space, with the exception of structure member and union member names. [MISRA C 2004]

The use of underscore is just a convention that some people follow. You can follow other conventions, e.g.

typedef struct sTag_lwm2m_object_t lwm2m_object_t;

struct sTag_lwm2m_object_t {
//
}

1 https://en.wikipedia.org/wiki/MISRA_C

Upvotes: 7

Bathsheba
Bathsheba

Reputation: 234875

Writing typedef struct _lwm2m_object_t lwm2m_object_t; means that you don't need to write the more verbose struct _lwm2m_object_t when you want to refer to the struct type, but you can use lwm2m_object_t directly instead. It saves typing and can make source code clearer.

Prefixing the actual struct name with a single _ is a convention that's grown up over the years. And many folk use _t as a suffix to denote a type.

But a few things to note:

  1. Don't ever use a double underscore, as formally the behaviour on doing that is undefined.

  2. Don't start a type with a single underscore followed by a capital letter. Again, such type names are reserved.

  3. POSIX explicitly forbids your ending your own type with _t, but note that standard C allows it.

Many experienced C programmers find (3) abhorrent and ignore it. (I do.)

Upvotes: 4

Related Questions