【问题标题】:Compilation error while including header file in compile command在编译命令中包含头文件时出现编译错误
【发布时间】:2020-11-17 10:47:21
【问题描述】:

我有两个文件 main.cheader.c

main.c 有一些宏STR 我想根据文件中的一些#define 有条件地定义其值。

案例 1

当我在main.c 文件中包含header.c 时,程序运行良好,如下所示:

ma​​in.c

#include<stdio.h>

#define _flag_b
#include "header.c"

void main(){
    printf("%s", STR);
}

header.c

#ifndef _flag_a
#define STR "flag a is activated.\n" 
#endif

#ifndef _flag_b
#define STR "flag b is activated.\n" 
#endif

编译

anupam@g3:~/Desktop/OS 2020/so$ gcc main.c
anupam@g3:~/Desktop/OS 2020/so$ ./a.out
flag a is activated.

案例 2

但由于某种原因,我想在编译命令中包含header.c,而不是在main.c 中。如下所示,这为我创造了这个问题:

ma​​in.c

#include<stdio.h>

#define _flag_b
// #include "header.c"

void main(){
    printf("%s", STR);
}

header.c

#ifndef _flag_a
#define STR "flag a is activated.\n" 
#endif

#ifndef _flag_b
#define STR "flag b is activated.\n" 
#endif

编译

anupam@g3:~/Desktop/OS 2020/so$ gcc main.c header.c
main.c: In function ‘main’:
main.c:7:15: error: ‘STR’ undeclared (first use in this function)
    7 |  printf("%s", STR);
      |               ^~~
main.c:7:15: note: each undeclared identifier is reported only once for each function it appears in
header.c:6: warning: "STR" redefined
    6 | #define STR "flag b is activated.\n"
      | 
header.c:2: note: this is the location of the previous definition
    2 | #define STR "flag a is activated.\n"
      | 

我对这个问题做了很多研究,并且能够理解为什么会出现这个问题。但我无法解决这个问题。

请帮助我更好地理解这个问题并提出一些解决方案。也帮我改写问题。

【问题讨论】:

  • 你为什么要这样做?标头应包含在内,而不是编译。
  • 注意str不是变量;它是一个宏。为避免混淆,约定使用大写标识符:#define STR
  • 在我们项目的测试文件中,我有类似的测试结构,他们希望根据定义的适当宏来定义不同的函数。
  • 命令行定义请见4.1 Defining macros

标签: c compilation macros ifndef


【解决方案1】:

#define 为预处理器定义了一个宏-这意味着在编译之前,已定义宏的每个实例(在其定义之后)都被替换,在您的情况下,在 #define STR 之后 ...每个 STR 实例都被替换为指定的常量.更多关于宏here

#include 只是复制一个文件并将其粘贴到指定位置。更多关于标题here

第一个示例有效,因为您包含了标题并且代码如下所示:

/*
  stuff included by stdio.h
*/
int main(void) {
  printf("%s", "flag a is activated.\n");
}

而且它可以很容易地编译。但在第二个示例中,您尝试分别编译每个文件,因此第一个文件如下所示:

/*
  stuff included by stdio.h
*/
int main(void) {
  printf("%s", STR); //preprocessor doesn't recognise STR as a macro
}

第二个文件是空的。所以现在编译器试图编译它,它不知道 STR 是什么,所以你有一个错误。

如果您想将其保留为#define,则需要包含标题。

您可以阅读有关预处理的更多信息here。如果要查看预处理器的输出,则需要使用 -E 标志,例如:gcc main.c -E -o mainPreprocessed.c

请下次将代码作为文本而不是图像包含在内 - 人们会更容易回答。

还有一件事:*.c 文件用于代码(您在 g++ 命令中添加),*.h 文件用于标头(您包含在 #include 中)。

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    相关资源
    最近更新 更多