proof1 发表于 2024-12-2 16:05

C++ 多文件协作问题

本帖最后由 proof1 于 2024-12-2 16:15 编辑

program.cpp            main()所在的主文件
function.h                头文件,用于声明函数
function.cpp             用于定义函数,内容如下:
-----------------------------------------
#include "function.h"

intAST;            //测试代码
AST=8888;      //测试代码,编译报错

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}
-----------------------------------------

测试代码intAST;    AST=8888;若插入函数体中,比如add(){          },则编译正常。
若不属于任何函数体,则 intAST;通过。
AST=8888; 报错:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2086: 'int AST' : redefinition

问题:这两行测试代码,若写在主文件 program.cpp中,且不属于任何函数体,则属于全局变量。可以正常编译。
   若在非主文件 function.cpp中,且不属于任何函数体。intAST;或者intAST=88; 能够通过,属于哪种范围变量?是否执行不到它?
   C++ 多文件协作,是一个什么规则?


UNICORN00 发表于 2024-12-2 16:09

本帖最后由 UNICORN00 于 2024-12-2 16:12 编辑

编辑-感觉不太行

proof1 发表于 2024-12-2 16:18

前两天发的问题求助贴,算是找到原因了,是一个低级错误?!
https://bbs.saraba1st.com/2b/thread-2208757-1-1.html

被子十三 发表于 2024-12-3 01:02

你的int AST只是声明,并没有定义,给它赋值的时候才是真正地在定义这个全局变量。
C++全局变量默认是有外部链接性的,可以被其它编译到同一个程序里的文件引用。你在测试代码里又重新定义了这个变量当然就会报错了。在你的测试代码里如果写成
extern int AST;
声明这个是外部变量,或者在function.cpp里定义的时候写成
static int AST;
应该就能避免这个问题。

当然全局变量一般都很危险,最好不要养成这种坏的代码习惯。真的需要全局变量的时候我们一般会把它放在一个匿名的命名空间里:

namespace {
int AST = 42;
}

— from OnePlus CPH2583, Android 15 of S1 Next Goose v2.5.2-play

随风来去 发表于 2024-12-3 02:20

ast还在其他地方有定义吗

-- 来自 有消息提醒的 Stage1官方 Android客户端

痴货 发表于 2024-12-3 05:40

这两行测试代码,若写在主文件 program.cpp中,且不属于任何函数体,则属于全局变量。可以正常编译。

这个即使在program.cpp作为全局变量也编不过去吧,我还特意试了下gcc。没有包在任何函数体里面的变量不能像在函数体里面那样直接对变量赋值。

在函数体外的“intAST; ” 相当于是定义了一个外部可见的全局变量,任何包含当前定义的文件在编译过程中会有重定义的错误。

痴货 发表于 2024-12-3 05:43

被子十三 发表于 2024-12-3 01:02
你的int AST只是声明,并没有定义,给它赋值的时候才是真正地在定义这个全局变量。
C++全局变量默认是有外 ...

这个不太准确。在全局的“int AST;” 等价于“extern int AST{};”,这其实已经定义了这个全局变量。

小岛幸子 发表于 2024-12-3 06:14

本帖最后由 小岛幸子 于 2024-12-3 06:39 编辑

c又不是python,写在函数外面的语句不会得到执行的。可以声明一个变量的时候同时赋值,但不能分成两段,认为会按顺序执行下去

对编译器来说,第一行你声明了一个a,虽然没有赋值默认为零。第二行你又声明了第二个a,这个a你不仅没有定义类型,并且与前一个a冲突了。这是两个声明,不是按顺序执行

编译器不负责执行这一部分的,只负责检查你调用的时候,有没有这个符号,符号是不是重复了,并且把符号的所在的地址插入到代码处

小岛幸子 发表于 2024-12-3 07:15

本帖最后由 小岛幸子 于 2024-12-3 07:56 编辑

多文件协作你可以这么看,.h理想情况下只负责声明符号,比如全局变量就 extern int a; 函数就 void b(); 相当于公开的接口,其他使用到这些符号的cpp文件都会include这个.h。可以声明无数次

然后同名的cpp文件就负责定义,int a = 1; void b(){...};这里的a和b都是全局的,所有的cpp文件里只能定义一次。实际上定义在任何一个cpp文件里都可以

如果只想在单个cpp文件内部使用,就在cpp文件里使用static。static int a = 2; static void b{...}; 这样其他文件看不到这个符号,也不会和全局的符号冲突

wave14 发表于 2024-12-3 19:39

以我大二程度的编程水平,也看出你没有extern变量
页: [1]
查看完整版本: C++ 多文件协作问题