如果这个C代码没有包含正确的头文件,它将如何编译?

ufj5ltwl  于 2023-01-04  发布在  其他
关注(0)|答案(1)|浏览(135)

我从口袋妖怪绿宝石反编译代码库中得到一个头文件(https://github.com/pret/pokeemerald)使用不同头文件中定义的类型,但不包括该头文件,或包括任何头文件,但代码仍然以某种方式编译。我的neovim LSP说,例如u8bool8类型无法识别,因为不包括gba/types.h头文件。然而,我的VScode LSP使用intellisense由于某种原因识别这些类型。有人知道这里发生了什么吗?这里是否发生了某种隐式包含?这些类型在整个代码库中使用,我搜索了“#include "gba/“,几乎没有出现。所以这些头文件没有被包含在源文件或头文件中,但不知何故代码还是被编译了。
头文件使用的类型不包括用于引用的头:

// file name: include/field_control_avatar.h
#ifndef GUARD_FIELDCONTROLAVATAR_H
#define GUARD_FIELDCONTROLAVATAR_H

struct FieldInput
{
    bool8 pressedAButton:1;
    bool8 checkStandardWildEncounter:1;
    bool8 pressedStartButton:1;
    bool8 pressedSelectButton:1;
    bool8 heldDirection:1;
    bool8 heldDirection2:1;
    bool8 tookStep:1;
    bool8 pressedBButton:1;
    bool8 input_field_1_0:1;
    bool8 input_field_1_1:1;
    bool8 input_field_1_2:1;
    bool8 input_field_1_3:1;
    bool8 input_field_1_4:1;
    bool8 input_field_1_5:1;
    bool8 input_field_1_6:1;
    bool8 input_field_1_7:1;
    u8 dpadDirection;
};

void FieldClearPlayerInput(struct FieldInput *pStruct);
void FieldGetPlayerInput(struct FieldInput *pStruct, u16 keys, u16 heldKeys);
int ProcessPlayerFieldInput(struct FieldInput *pStruct);
void overworld_poison_timer_set(void);
void RestartWildEncounterImmunitySteps(void);
const u8 *GetObjectEventScriptPointerPlayerFacing(void);
bool8 TryDoDiveWarp(struct MapPosition *position, u16 b);
int SetCableClubWarp(void);
u8 TrySetDiveWarp(void);
const u8 *GetInteractedLinkPlayerScript(struct MapPosition *position, u8 metatileBehavior, u8 direction);
u8 *GetCoordEventScriptAtMapPosition(struct MapPosition *position);
void ClearPoisonStepCounter(void);

#endif // GUARD_FIELDCONTROLAVATAR_H

老实说,我并不觉得代码编译有什么奇怪的,因为它使用了一个叫做agbcchttps://github.com/pret/agbcc)的特殊编译器,也许编译系统会自动包含这些文件。但是我的VSCode LSP只是使用了clang,但是它识别这些类型却没有包含头文件。所以我不确定发生了什么。

a64a0gku

a64a0gku1#

似乎该存储库中的几乎每个C文件都以#include "global.h"开头,其开头为:

#include <string.h>
#include <limits.h>
#include "config.h" // we need to define config before gba headers as print stuff needs the functions nulled before defines.
#include "gba/gba.h"
#include "constants/global.h"
#include "constants/flags.h"
#include "constants/vars.h"
#include "constants/species.h"
#include "constants/pokedex.h"
#include "constants/berry.h"
#include "constants/maps.h"
#include "constants/pokemon.h"
#include "constants/easy_chat.h"
#include "constants/trainer_hill.h"

并且gba/gba. h以如下形式开始:

#include "gba/defines.h"
#include "gba/io_reg.h"
#include "gba/types.h"
#include "gba/multiboot.h"
#include "gba/syscall.h"
#include "gba/macro.h"
#include "gba/isagbprint.h"

所以包含是传递性的。
我没有进一步研究,但大概这就是它的全部编译方式。

相关问题