main.c 定义 foo,然后包含 library.c。为什么 cpptools 无法识别library.c 中的foo?

问题描述 投票:0回答:2

我有两个C文件,

main.c
library.c
,其中包含以下内容:

// main.c
#include <stdio.h>

int MY_NUMBER = 6;

#include "library.c"

int main() {
    change_the_number();
    printf("The number: %d\n", MY_NUMBER);
}
// library.c
void change_the_number() {
    MY_NUMBER = 5;
}

运行

gcc main.c -o main
,然后运行
main
,我得到输出
The number: 5
,这正是我所期望的。

VSCode 在

MY_NUMBER
中对
library.c
下划线,抱怨“标识符
MY_NUMBER
未定义”。就我而言,这也是预期的行为 - 仅查看
library.c
,没有任何内容表明
MY_NUMBER
是什么或它来自哪里。

如何配置 Microsoft 的 C/C++ 扩展来识别

MY_NUMBER

到目前为止我尝试过的:

  • ${workspaceFolder}
    ${workspaceFolder}/**
    添加到
    C-Cpp > Default: Include Path
  • library.c
    更改为
    library.h
    (我真的认为这不会有任何作用,我是对的。)

一个限制是我无法更改代码 - 我必须设置 IDE 以允许这种声明/使用安排,因为我是一名实习生,并且这种模式在我的代码库中重复数百次(如果不是数千次)我正在努力。我会向我的同事寻求帮助,但他们都没有使用带有 C/C++ 扩展的 VSCode - 每个人都使用不同的东西。

最终,如果 MS C/C++ 扩展不支持这种事情,那很好,我只会使用其他东西,但我认为有趣的是,这个完全有效的 C 程序会被标记为有问题。

c visual-studio-code
2个回答
1
投票

万一有人偶然发现这一点,我想我应该分享我在阅读 @BoP 的答案后一段时间的认识 - 随着代码库规模的增长,我希望 linter 做的事情变得越来越困难,以至于难处理。

如果您开始尝试以我在问题中所示的方式包含

.c
文件,事情会变得有点复杂,因为您可以有一个常量 - 在我们的例子中为
MY_NUMBER
- 在原始文件中声明,并且在包含的文件中使用。这是有效的 C,如上所示。

但是 - 如果您只获取包含的文件(我的问题中的

library.c
),并与其余代码隔离地查看它,您不知道哪些代码可以包含该
.c
文件。 它可以是您计算机上的任何源代码。 linter 显然无法扫描您的整个计算机,因此问题很棘手,并且没有 linter 可以有效地完成我想要的事情。

这个故事的寓意 - 正确使用 C。


0
投票

这是一个奇怪的模式。我看不到上下文,因此从这个最小的示例中,我想在库标头中声明变量 extern,在库中的源文件中定义它,并包含定义它的标头,并且无论变量在库内部还是外部使用。

但是让我们一起来想象一下,如果没有更多的上下文,我就看不到一个很好的理由。从技术上讲,IntelliSense/静态代码分析工具可以根据两个 .c 文件将其拼凑在一起。但这将是一个权衡。如果不了解如何从这些文件构建程序(以及它们是否一起使用或在其他程序中使用),这将是正确性/准确性的权衡。如果文件打算包含在分析工具知道的文件之外的另一个源中,如果这些文件没有定义包含的文件期望存在的变量怎么办?分析工具应该做什么?我不知道这个问题是否有一个全球范围内没有争议的答案。

现在,让我们摆脱理论迷雾,回到现实,使用 VS Code 的 cpptools 扩展。我认为至少有一种方法可以解决这个问题。请参阅有关让 IntelliSense 工作的官方文档。您可以定义一个compile_commands.json 文件,对于包含的文件,您可以传递编译器标志来定义与预期变量同名的宏,并将其定义为与预期变量类型相同类型的某个值。但是......至少根据我的经验,通常compile_commands.json是由构建工具机器生成的,而不是手工编写的。既然您说这是代码库中的常见模式,您可以研究为此生成compile_commands.json 文件的可行性。我不知道如果您走这条路,您是否需要为所有您的文件填写正确的条目。

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