C 中具有循环依赖的文件编译顺序

问题描述 投票:0回答:1
/*
 * structs.h
 *
 *  Created on: 14 Jun 2019
 */
#ifndef STRUCTS_H_
#define STRUCTS_H_
    
#include <stdint.h>
#include "line_mask.h"
    
#define CONFIG_LINE_NUM                 80
    
#endif
/*
* line_mask.h
*
*  Created on: 15 Nov 2019
*/
    
#ifndef LINE_MASK_H_
#define LINE_MASK_H_
    
#include "../Inc/structs.h"
    
typedef struct
{
#if CONFIG_LINE_NUM <= 64
    uint64_t line_mask[1];
#elif (CONFIG_LINE_NUM <= 128)
    uint64_t line_mask[2];
#elif (CONFIG_LINE_NUM <= 192)
    uint64_t line_mask[3];
#elif (CONFIG_LINE_NUM <= 256)
    uint64_t line_mask[4];
#else
#error "Unsupported CONFIG_LINE_NUM value"
#endif
} LineMask;
#endif

你好。你能给我解释一下吗?我编写了头文件相互引用的代码,以便使用定义。结果,文件 line_mask.h 似乎是在 structs.h 之前编译的(当我在文件 line_mask.h 中添加 #ifdef CONFIG_LINE_NUM 检查时证实了这一点)。因此,在定义结构体 LineMask 时,变量 CONFIG_LINE_NUM 并不存在。

在这种情况下,为什么编译器没有报告错误,而是可能用 0 替换该变量,从而使用数组 line_mask[1] 创建一个结构体?

还有第二个问题:在创建了这样一个结构体之后,在某个模块的初始化过程中,该结构体是用line_mask[1]初始化的,但是在程序的后面,在不同的部分,该结构体是用line_mask[2]创建的],导致复制时内存泄漏。

尽管头文件中存在 #ifndef LINE_MASK_H_ 条件,为什么在声明 CONFIG_LINE_NUM 指令后 LineMask 结构的定义会发生变化?

c compiler-errors c-preprocessor header-files circular-dependency
1个回答
0
投票

在这种情况下,为什么编译器没有报告错误,而是可能用 0 替换该变量,从而使用数组 line_mask[1] 创建一个结构体?

C 2018 6.10.1 4 说:

…在执行完所有由于宏扩展和

defined
一元运算符引起的替换后,所有剩余的标识符(包括词法上与关键字相同的标识符)都被替换为pp-number
0
,然后每个预处理标记都被转换为一个代币。

因此,在

#if CONFIG_LINE_NUM <= 64
中,
CONFIG_LINE_NUM
被替换为
0

还有第二个问题:在创建了这样一个结构体之后,在某个模块的初始化过程中,该结构体是用line_mask[1]初始化的,但是在程序的后面,在不同的部分,该结构体是用line_mask[2]创建的],导致复制时内存泄漏。

这是由不同的代码引起的,您没有显示,因此无法明确回答。

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