为什么在c中使用下划线作为结构?

问题描述 投票:0回答:4

在下面的源代码中,有人可以解释理性(为什么typedef使用新名称qa​​zxswpoi对_lwm2m_object_t进行良好的编程实践?它所做的只是删除下划线?为什么在第一个实例中使用下划线?

lwm2m_object_t
c struct standards typedef
4个回答
6
投票

实际上如果你使用

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;
};

C仍然允许它。这是因为结构名称和typedef标识符具有不同的名称空间。有关C中命名空间的信息,请参阅typedef struct lwm2m_object_t lwm2m_object_t; struct lwm2m_object_t { // }

但是,许多专业用户会避免这种情况,并对结构和typedef使用不同的名称。 MISRA1也不允许这样做。

规则5.6(建议):一个名称空间中的标识符与另一个名称空间中的标识符不应具有相同的拼写,但结构成员和联合成员名称除外。 [MISRA C 2004]

使用下划线只是一些人遵循的惯例。您可以遵循其他约定,例如

Why doesn't ANSI C have namespaces?

1 typedef struct sTag_lwm2m_object_t lwm2m_object_t; struct sTag_lwm2m_object_t { // }


1
投票

编写https://en.wikipedia.org/wiki/MISRA_C意味着当你想引用typedef struct _lwm2m_object_t lwm2m_object_t;类型时你不需要编写更详细的struct _lwm2m_object_t,但你可以直接使用struct。它可以节省输入并使源代码更清晰。

使用单个lwm2m_object_t前缀实际的struct名称是一种多年来成长的惯例。许多人使用_作为后缀来表示一种类型。

但有几点需要注意:

  1. 不要使用双下划线,正如这样做的行为是未定义的。
  2. 不要使用单个下划线后跟大写字母来启动类型。同样,保留了这种类型名称。
  3. POSIX明确禁止使用_t结束自己的类型,但请注意标准C允许它。

许多经验丰富的C程序员发现(3)令人厌恶并忽略它。 (我做。)


0
投票

领先的下划线由每个人或团队用于不同的目的。在这个_t中阅读更多内容,特别是专用于answer的段落。

我经常看到这个:

其中一个将typedef struct lwm2m_object lwm2m_object_t; 附加到结构的名称,向读者表明这是一个typedef'ef名称。


0
投票

就其本身而言,前导下划线没有内在含义,它只是为标记名称和typedef名称创建了一个不同的标识符。你可以用相同的结果

_t

标记名称与普通标识符占用不同的名称空间,因此您可以编写

typedef struct foo fooType;

有些人认为这令人困惑。我没有 - 标签名称由typedef struct foo foo; (或structunion)关键字的存在消除歧义。

您不应在标识符中使用前导下划线 - 具有两个前导下划线的标识符或后跟大写字母的前导下划线始终保留用于任何用途的实现,而具有单个前导下划线的标识符保留在普通和标记名称空间中。

您可以使用尾随下划线来获得相同的效果

enum

并满足每个人。

© www.soinside.com 2019 - 2024. All rights reserved.