Typedef在其他标头中声明,包含在必要的文件中,但是产生:错误[Pe020]:标识符""未定义。为什么?

时间:2016-02-03 17:23:37

标签: c header-files iar

让我们说我在IAR的C项目,我正在使用这4个文件。我有一个定义头,另一个外部函数头。我还有两个.c文件,一个用于main,一个用于函数,如下所示。

第一个头文件:header1.h

#ifndef __HEADER1_H
#define __HEADER1_H

#include "header2.h"
#include "otherheader.h"

// bunch of 'define' here
typedef uint8_t   macAddr[8];
#endif

另一个头文件:header2.h

#ifndef __HEADER2_H
#define __HEADER2_H

//other extern functions here
extern void getMAC(macAddr deviceAddr);
#endif

main.c文件在这里:

#include "header1.h"
void main ()
{
    macAddr dev1Address = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    getMAC(dev1Address);
}

function.c文件在这里:

#include "header1.h"
void getMAC(macAddr deviceAddr)
{ 
  uint8_t transmit[8];
  for (int i = 0; i<8; i++)
      transmit[i] = deviceAddr[i];
}

报告的错误是:

Error[Pe020]: identifier "macAddr" is undefined 

我很难理解为什么这不起作用。第一个标头(其中定义了macAddr)包括第二个标头(声明getMac()函数),第一个标头包含在main.c和function.c中。据我所知,没有循环包含(如其他问题所示......如果我错了,请纠正我,并告诉我如何)

1 个答案:

答案 0 :(得分:1)

问题是header1.h包含header2.h,但header2.h需要macAddr尚未定义。

经验法则是每个文件应仅包含所需的文件。因此:

  • header1.h只有一个typedef。它应该只包含stdint.h
  • header2.h需要macAddr才能运作,因此应该包含header1.h
  • main.c使用getMAC,因此应包含header2.hheader1.h已经包含在内,因此无需包含它。
  • function.c严格只需要header1.h,但确保函数声明和定义匹配是一种很好的做法,因此它应该包含header2.h

似乎header1.h被用作整体标题,用于包含所有内容(很难确定,因为您的示例文件太少)。这是非常糟糕的练习。它可以增加编译时间,并且由于难以跟踪依赖性而使重构变得困难。

理想情况下,每个标题应该只有一个明确定义的责任。它并非总是可行,但它是一个很好的目标。

只要您使用标题保护,循环包含不是一个大问题,除非需要,否则不包括所有地方。有时您可能需要添加额外的前向声明,但这是关于它的。

以下是一些补充说明:

  • 正如user3629249和其他人所说,你真的不应该声明以_下划线开头的符号。这些保留用于C标准或编译器使用。

  • 我不建议在数组(或指针)上使用typedef。在某些情况下,数组会在没有告诉您的情况下衰减到指针,因此在使用typedef时,这对用户是隐藏的,并且可能会导致错误使用。我会把它换成struct:
    typedef struct { uint8_t address[8]; } MAC_T;