【问题标题】:declare a struct in header as a typedef将 header 中的结构声明为 typedef
【发布时间】:2019-04-26 07:28:48
【问题描述】:

我正在尝试将结构定义为头文件中的 typedef 并在许多来源中使用它。我在here 中找到了类似的答案,但我不确定是否可以将 typedef 定义为 extern。 msg_encoded 也应该有一个默认值。

// lib.h

#ifndef lib_h
#define lib_h

struct msg_encoded_s
{
    uint8_t msg[10];
    int length;
} msg_encoded_default = {{0}, 0};

typedef struct msg_encoded_s msg_encoded;

#endif

// lib.c

#include "lib.h"

msg_encoded some_var;

// main.c

# include "lib.h"
int main(){
    msg_encoded some_other_var;
}

main.o:(.bss.msg_encoded_default+0x0): 多重定义 `msg_encoded_default'

【问题讨论】:

  • @JohnnyMopp 我应该同时制作msg_encoded_defaultmsg_encoded extern 吗?
  • 如果您将该头文件包含在程序中的多个源模块中,那么每个源模块都定义了msg_encoded_default。您应该在一个源模块中定义msg_encoded_default,然后在标题中定义extern (extern msg_encoded msg_encoded_default;)
  • 错误不是由typedef引起的。这是由msg_encoded_default 变量引起的。
  • 既然你有 typedef,你可以使用 typedef 声明 msg_encoded_default 变量。例如。在“lib.h”中声明extern msg_encoded msg_encoded_default;,在“lib.c”中声明msg_encoded msg_encoded_default = {{0}, 0};

标签: c struct


【解决方案1】:

类似的“声明”

struct msg_encoded_s {
   ...
} msg_encoded_default;

实际上是 (1) 一个名为 msg_encoded_sstruct 类型的定义和 (2) 一个名为 `msg_encoded_default 的类型的变量的定义

因此,如果您将此头文件包含在单独的翻译单元中,那么您将重新定义一个名为 msg_encoded_default 的变量,这是不允许的。

要克服这个问题,请编写一个类似...的标题

typedef struct msg_encoded_s
{
    uint8_t msg[10];
    int length;
} msg_encoded;

extern msg_encoded msg_encoded_default;

在一个翻译单元中写:

#include "myheader.h"
msg_encoded msg_encoded_default = {{0}, 0};

在所有其他翻译单元中只写...

#include "myheader.h"
...
int test = msg_encoded_default.length;  // or something like this

【讨论】:

  • 谢谢,为什么你在.c而不是.h中设置默认值?
  • 默认值设置在变量定义的地方,而extern msg_encoded msg_encoded_default;只是一个声明
  • +1 可以很好地解释 C 中变量的声明和定义之间的区别。[参见 Johnathan Leffler 的帖子] (stackoverflow.com/a/1433387/7508077)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-27
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
相关资源
最近更新 更多