You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写C语言解释器时编译器无法识别自定义函数求助

编译C自定义函数未识别问题排查与解决

问题描述

跟随《Crafting Interpreters》一书用C语言实现编程语言,包含多个头文件、对应C文件及主驱动代码。编译时编译器无法识别自定义函数(如initChunk、writeChunk、freeChunk),但其他使用头文件的项目可正常编译。相关代码如下:

main.c

#include "common.h"
#include "chunk.h"

int main(int argc, const char* argv[]) {
    Chunk chunk;
    initChunk(&chunk);
    writeChunk(&chunk, OP_RETURN);
    freeChunk(&chunk);
    return 0;
}

common.h

#ifndef clox_common_h
#define clox_common_h

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#endif

chunk.h

#ifndef clox_chunk_h
#define clox_chunk_h

#include "common.h"

typedef enum {
    OP_RETURN,
} OpCode;

typedef struct {
    int count;
    int capacity;
    uint8_t* code;
} Chunk;

void initChunk(Chunk* chunk);
void freeChunk(Chunk* chunk);
void writeChunk(Chunk* chunk, uint8_t byte);

#endif

chunk.c

#include <stdlib.h>

#include "chunk.h"
#include "memory.h"

void initChunk(Chunk* chunk) {
    chunk->count = 0;
    chunk->capacity = 0;
    chunk->code = NULL;
}

void freeChunk(Chunk* chunk) {
    FREE_ARRAY(uint8_t, chunk->code, chunk->capacity);
    initChunk(chunk);
}

void writeChunk(Chunk* chunk, uint8_t byte) {
    if (chunk->capacity < chunk->count) {
        int oldCapacity = chunk->capacity;
        chunk->capacity = GROW_CAPACITY(oldCapacity);
        chunk->code = GROW_ARRAY(uint8_t, chunk->code, 
            oldCapacity, chunk->capacity);
    }

    chunk->code[chunk->count] = byte;
    chunk->count++;
}

memory.h

#ifndef clox_memory_h
#define clox_memory_h

#include "common.h"

#define GROW_CAPACITY(capacity) \
    ((capacity) < 8 ? 8 : (capacity) * 2)

#define GROW_ARRAY(type, pointer, oldCount, newCount) \
    (type*)reallocate(pointer, sizeof(type) * (oldCount), \
        sizeof(type) * (newCount))

#define FREE_ARRAY(type, pointer, oldCount) \
    reallocate(pointer, sizeof(type) * (oldCount), 0)

void* reallocate(void* pointer, size_t oldSize, size_t newSize);

#endif

memory.c

#include <stdlib.h>

#include "memory.h"

void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
    if (newSize == 0) {
        free(pointer);
        return NULL;
    }

    void* result = realloc(pointer, newSize);
    if (result == NULL) exit(1);
    return result;
}

问题原因

核心原因是编译时未将所有依赖的.c源文件纳入编译流程。头文件仅提供函数声明,函数的实际实现存在于.c文件中。如果只编译main.c,编译器无法找到initChunk等函数的定义,就会报“未识别函数”的链接错误。

解决方法

方法1:一次性编译所有源文件

使用gcc时,执行以下命令将所有相关.c文件一起编译并链接:

gcc main.c chunk.c memory.c -o clox

此命令会同时编译所有源文件,并将生成的目标文件链接成可执行程序clox。

方法2:分步编译生成目标文件再链接

先单独编译每个.c文件为目标文件(.o):

gcc -c main.c -o main.o
gcc -c chunk.c -o chunk.o
gcc -c memory.c -o memory.o

再将所有目标文件链接成可执行程序:

gcc main.o chunk.o memory.o -o clox

额外代码问题提示

writeChunk函数中的扩容判断条件存在逻辑错误:当前条件if (chunk->capacity < chunk->count)会导致初始状态(capacity=0、count=0)下不触发扩容,首次写入时会访问NULL指针chunk->code,引发程序崩溃。应修改为:

if (chunk->count >= chunk->capacity) {
    // 扩容逻辑
}

内容的提问来源于stack exchange,提问作者Chubbs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 19:30:38