外部变量的问题

发布于 2024-09-02 22:45:21 字数 405 浏览 2 评论 0原文

我有 2 个 cpp 文件 &一个头文件,我已将其包含在两个 cpp 文件中。是这样的:

abc.h

extern uint32_t key;

a.cpp

#include "abc.h"
uint32_t key;
int main
{
.............
}

b.cpp

#include "abc.h"

int main
{
printf("Key: %.8x\n", key);
.............
}

现在当我编译a.cpp时,没有错误。但是当我编译 b.cpp 时出现错误 “对‘key’的未定义引用”。请帮我找出这段代码中的问题。

I have got 2 cpp files & a header file, which I have included in both cpp files. It's like this:

abc.h

extern uint32_t key;

a.cpp

#include "abc.h"
uint32_t key;
int main
{
.............
}

b.cpp

#include "abc.h"

int main
{
printf("Key: %.8x\n", key);
.............
}

Now when I compile a.cpp, there is no error. but when i compile b.cpp it gives error
"undefined reference to `key'". Please help me in finding the problem in this code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

篱下浅笙歌 2024-09-09 22:45:21

要共享变量,通常需要这样的操作:

// A.h
extern int key;
void show();

//a.cpp
#include "a.h"

int main() { 
    key = 1;
    show();
};

// b.cpp
#include "a.h"
#include <iostream>

int key;

void show() { std::cout << "Key = " << key; }

这里有几点需要注意。首先,将 extern 声明放入标头中,并将其包含在所有使用该变量的文件中。在一个且仅一个文件中定义变量(不带 extern)。只有一个文件应包含名为 main 的函数。

编辑:要构建此文件,您需要单独编译每个文件,但必须将两个文件链接在一起。例如,使用 gcc,您可以执行以下操作:

gcc -c a.c
gcc -c b.c
gcc a.o b.o

第一个编译(但不链接) ac 第二个对 bc 执行相同操作 第三个实际上将两者链接在一起并生成可以执行的二进制映像(传统上称为 a .out,但是,例如,在 Windows 上,这通常更改为 a.exe)。

To share a variable, you normally have something like this:

// A.h
extern int key;
void show();

//a.cpp
#include "a.h"

int main() { 
    key = 1;
    show();
};

// b.cpp
#include "a.h"
#include <iostream>

int key;

void show() { std::cout << "Key = " << key; }

There are a couple of points to not here. First of all, you put the extern declaration in a header, and include it in all the files that use the variable. Define the variable (without the extern) in one and only one file. Only one file should contain a function named main.

Edit: to build this, you compile each file by itself, but you have to link the two files together. For example, using gcc you could do something like:

gcc -c a.c
gcc -c b.c
gcc a.o b.o

The first compiles (but does not link) a.c. The second does the same with b.c The third actually links the two together and produces a binary image you can execute (traditionally named a.out, though, for example, on Windows this is normally changed to a.exe).

最单纯的乌龟 2024-09-09 22:45:21

问题正是错误消息所说的。 Abc.h 声明变量,但没有定义它。 a.cpp 中的行定义了它。也就是说,a.cp​​p是变量的物理存储出现的地方。 b.cpp 中没有这样的行,因此当您尝试编译该程序时,链接器不会为该变量定义任何存储。

如果您在标头中省略了“extern”说明符,则 b.cpp 可以正常编译,但 a.cpp 可能会给出有关多个定义的错误。

当单个程序中有多个源文件时,“extern”说明符发挥更大的作用。在这种情况下,它们可能都包含 abc.h,但如果没有“extern”,每个编译的目标文件都会有自己对同一变量的独立定义。链接器通常不知道该怎么做,并且可能会抱怨,尽管我认为不需要这样做。修复方法是使用“extern”,这样每个编译的文件文件只有一个声明。然后,您选择一个源文件来放置定义。您可能会将其放入 abc.cpp 中,因为声明位于 abc.h 中。

The problem is exactly what the error message says. Abc.h declares the variable, but it doesn't define it. The line in a.cpp defines it. That is, a.cpp is where the physical storage of the variable appears. There is no such line in b.cpp, so when you try compiling that program, the linker is left without any storage defined for that variable.

If you had omitted the "extern" specifier in the header, then b.cpp would have compiled fine, but a.cpp would likely have given an error about multiple definitions.

The "extern" specifier plays a larger role when you have multiple source files in a single program. In that case, they would probably all include abc.h, but without "extern," each compiled object files would have its own independent definition of the same variable. The linker generally won't know what to do with that, and will probably complain, although I don't think it's required to do so. The fix is to use "extern" so each compiled file file only has a declaration. Then you pick one source file to place the definition in. You'd probably put it in abc.cpp since the declaration is in abc.h.

风流物 2024-09-09 22:45:21

头文件中的这一行是一个声明;它告诉编译器该变量存在,但不为其分配任何空间。当您从一个或多个源文件构建程序时,其中一个文件还必须包含定义。

就您而言,您在 a.cpp 中有一个定义,因此它包含构建程序所需的所有内容。 b.cpp没有定义,所以链接失败。

有两种解决方案。将定义从 a.cpp 复制到 b.cpp,或者将其移动到第三个源文件,并在构建两个程序时将其包含在源列表中。

The line from the header file is a declaration; it tells the compiler that the variable exists, but doesn't allocate any space for it. When you build a program from one or more source files, one of them must also contain a definition.

In your case, you have a definition in a.cpp, so that contains everything needed to build the program. b.cpp has no definition, so it will fail to link.

There are two solutions. Either copy the definition from a.cpp to b.cpp, or move it to a third source file and include that in the list of sources when building both programs.

三生殊途 2024-09-09 22:45:21

您正在编译两个单独的程序。一个程序不能引用另一个程序的变量。 extern 关键字用于引用链接的同一可执行文件的另一个目标文件中的一个目标文件中的符号。

You are compiling two separate programs. One cannot reference a variable from the other. The extern keyword is for referencing a symbol from one object file in another object file of the same executable being linked.

著墨染雨君画夕 2024-09-09 22:45:21

我猜你遇到了链接错误?链接 b 时需要包含 ao,但如果 a 和 b 中确实都有“main”,则不起作用。您需要制作声明密钥的 c.cpp,并将 co 链接到 a.exe 和 b.exe。

I am guessing you are getting a link error? You need to include a.o when linking b, though if you really have "main" in both a and b that won't work. You will need to make c.cpp which declares key, and link c.o into both a.exe and b.exe.

彩扇题诗 2024-09-09 22:45:21

a.cppb.cpp 都定义了 main() 函数,并且只允许定义一个 main( ) 每个程序。所以,我假设您想要做的是在两个程序之间共享头文件。在这种情况下,请将行添加到 b.cpp 中以定义 key 并重新编译:

uint32_t key;

这不是使用头文件的正常方法。相反,您编写函数以将 key 作为参数。这样做会设置一个全局变量,这通常是不受欢迎的。

extern 几乎总是用于设置全局变量(在我的脑海中,我想不出使用 extern 的任何其他原因)。但是,如果您想按照通常使用的方式使用 extern ,而不考虑是否应该使用它,您将执行以下操作:

  • 删除 main() 函数来自两个文件之一,出于本答案的目的,我们将从 b.cpp 中删除它。
  • 使用以下两行来编译和链接您的程序(假设是 gcc):

    gcc -c -o bo b.cpp

    gcc a.cpp bo

gcc-c 选项(第一行)表示“仅编译,不链接。"链接步骤决定了所有变量是否都已定义,它们在编译 b.cpp 时并未定义,但在编译 a.cpp 时已定义(第二行)。

Both a.cpp and b.cpp have main() functions defined, and you're only allowed to define one main() per program. So, I assume what you're trying to do is share a header file between two programs. In that case, add the line to b.cpp to define key and recompile:

uint32_t key;

This isn't the normal way to use header files. Instead you write your functions to take key as a parameter. Doing it this way sets up a global variable, which is generally frowned on.

extern is almost always used to set up a global variable (off the top of my head, I can't think of any other reason to use extern). But if you want to use extern the way it's normally used -- without going into whether it should be used at all -- you would do the following:

  • remove the main() function from one of the two files, for the purposes of this answer we'll remove it from b.cpp.
  • Use the following two lines to compile and link your program (assuming gcc):

    gcc -c -o b.o b.cpp

    gcc a.cpp b.o

The -c option to gcc (first line) says "compile only, do not link." It's the linking step that determines if all variables are defined, and they aren't defined when you compile b.cpp, but they are defined when you compile a.cpp (second line).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文