3_重复定义(MULTIPLE PUBLIC DEFINITIONS )

合集下载

KEILC51编译ERRORL104MULTIPLEPUBLICDEFINITIONS重复定义

KEILC51编译ERRORL104MULTIPLEPUBLICDEFINITIONS重复定义

KEILC51编译ERROR L104: MULTIPLE
PUBLIC DEFINITIONS重复定义
c/c++语言中有很多地方要用到extern,但是如果
没有真正的了解它的意义,会给编程带来很大的麻烦,
为了使大家少走弯路,特祥细的说明一下。

对于比较小的程序,一般只有一个c文件和一个头
文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。

如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量
i进行声明,在c文件的程序之前必须加上int i进行定义。

extern int i=0;这一句声明和定义都做了。

对于大一点的程序,有很多c文件和头文件,这个
时候全局变量就必须在头文件中声明(不需要初始化),
然后在一个c文件中定义(该初始化的要初始化)。

如果
在头文件中定义,则编译的时候会出现重复定义的错误。

如果只有头文件中声明就会出现没有定义有警告。

*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: K
MODULE: 222.obj (222)
出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)。

「keilc语言编程常见错误分析」

「keilc语言编程常见错误分析」

1.Warning 280:’i’:unreferencedlocal variable 说明局部变量i 在函数中未作任何的存取操作解决方法消除函数中i 变量的宣告及即定义的参数在程序中并未调用2Warning 206:’Music3’:missing function-prototype 说明Music3( )函数未作宣告或未作外部宣告所以无法给其他函数调用解决方法将叙述void Music3(void)写在程序的最前端作宣告如果是其他文件的函数则要写成extern voidMusic3(void),即作外部宣告3Error:318:can’t open file‘beep.h’说明在编译C:\8051\MANN.C程序过程中由于main.c 用了指令#i nclude “beep.h”,但却找不到所致解决方法编写一个beep.h的包含档并存入到c:\8051 的工作目录中ﻫ4 Error237:’LedOn’:function already has a body ﻫ说明LedOn()函数名称重复定义即有两个以上一样的函数名称ﻫ解决方法修正其中的一个函数名称使得函数名称都是独立的ﻫﻫ5 ***WARNING16:UNCALLED SEGMENT,IGNORED FOR OVERLAYPROCESSSEGMENT: ?PR?_DELAYX1MS?DELAY说明DelayX1ms( )函数未被其它函数调用也会占用程序记忆体空间解决方法去掉DelayX1ms()函数或利用条件编译#if …..#endif,可保留该函数并不编译ﻫ6***WARNING6 :XDATASPACE MEMORY OVERLAPFROM : 0025HTO: 0025H ﻫ说明外部资料ROM的0025H 重复定义地址解决方法外部资料ROM 的定义如下Pdata unsigned char XF R_ADC _at_0x25 其中XFR_ADC 变量的名称为0x25,请检查是否有其它的变量名称也是定义在0x25 处并修正它ﻫ7 WARNING206:’DelayX1ms’:missingfunction-prototypeﻫC:\8051\INPUT.CError 267 :’DelayX1ms ‘:requires ANSI-styleprototypeC:\8051\INPUT.C说明程序中有调用DelayX1ms 函数但该函数没定义即未编写程序内容或函数已定义但未作宣告解决方法编写DelayX1ms的内容编写完后也要作宣告或作外部8宣告可在delay.h 的包含档宣告成外部以便其它函数调用ﻫﻫ***WARNING1:UNRESOLVED EXTERNAL SYMBOLﻫSYMBOL:MUSIC3解决办法:1.是文件没有添加到工程里。

LINK2005错误——重复定义错误

LINK2005错误——重复定义错误

LINK2005错误——重复定义错误编程中经常能遇到LNK2005错误——重复定义错误,其实LNK2005错误并不是一个很难解决的错误。

弄清楚它形成的原因,就可以轻松解决它了。

造成LNK2005错误主要有以下几种情况:1.重复定义全局变量。

可能存在两种情况:A、对于一些初学编程的程序员,有时候会以为需要使用全局变量的地方就可以使用定义申明一下。

其实这是错误的,全局变量是针对整个工程的。

正确的应该是在一个CPP文件中定义如下:int g_Test;那么在使用的CPP文件中就应该使用:extern int g_Test即可,如果还是使用int g_Test,那么就会产生LNK2005错误,一般错误错误信息类似:AAA.obj error LNK2005 int book c?book@@3HA already defined in BBB.obj。

切记的就是不能给变量赋值否则还是会有LNK2005错误。

这里需要的是“声明”,不是“定义”!根据C++标准的规定,一个变量是声明,必须同时满足两个条件,否则就是定义:(1)声明必须使用extern关键字;(2)不能给变量赋初值所以,下面的是声明:extern int a;下面的是定义int a; int a = 0; extern int a =0;B、对于那么编程不是那么严谨的程序员,总是在需要使用变量的文件中随意定义一个全局变量,并且对于变量名也不予考虑,这也往往容易造成变量名重复,而造成LNK2005错误。

2.头文件的包含重复。

往往需要包含的头文件中含有变量、函数、类的定义,在其它使用的地方又不得不多次包含之,如果头文件中没有相关的宏等防止重复链接的措施,那么就会产生LNK2005错误。

解决办法是在需要包含的头文件中做类似的处理:#ifndef MY_H_FILE //如果没有定义这个宏#define MY_H_FILE //定义这个宏……. //头文件主体内容…….#endif上面是使用宏来做的,也可以使用预编译来做,在头文件中加入:#pragma once//头文件主体3.使用第三方的库造成的。

重复定义的错误MULTIPLE PUBLIC DEFINITIONS

重复定义的错误MULTIPLE PUBLIC DEFINITIONS

c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下。

对于比较小的程序,一般只有一个c文件和一个头文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。

如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量i进行声明,在c文件的程序之前必须加上int i进行定义。

extern int i=0;这一句声明和定义都做了。

对于大一点的程序,有很多c文件和头文件,这个时候全局变量就必须在头文件中声明(不需要初始化),然后在一个c文件中定义(该初始化的要初始化)。

如果在头文件中定义,则编译的时候会出现重复定义的错误。

如果只有头文件中声明就会出现没有定义有警告。

*** ERROR L104: MULTIPLE PUBLIC DEFINITIONSSYMBOL: KMODULE: 222.obj (222)出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)今天调试时遇到了这个问题,以前都不注意这些警告错误,现在看来争取要做到:0错误,0警告。

中断中和中断外都调用了同一个串口打印函数,一直有上述的报警,没在意,今天调试时发现串口打印出了一些乱七八糟的东东,且程序也不知道跑哪里去了,很郁闷。

最后查到是上述这个问题导致的,现在解决办法为采用第二种办法,第一种办法据说要耗很多存储空间,以后慢慢体会。

说说几个小问题吧,一般我们在用KEIL的时候,只要编译器报- 0 Error(s) 一般我们都不去管多少个 Warning(s).了,一般这样程序基本都能运行,但是其实仔细想想,这里还是有问题的,否则编译器没事吃饱了撑得,报什么警告啊~~~今天来说说*** WARNING L15: MULTIPLE CALL TO SEGMENT这个问题!其实这个问题应该是引起注意的,有可能引起程序冲突,但是一般时候程序运行不会有问题,但是如果出来问题,那将会是很讨厌的问题.分析一下产生这一警告的一个根源是:例如在主循环里调用了一个函数,而在中断服务中,你又一次调用了同样的函数。

命名空间namespace,以及重复定义的问题解析

命名空间namespace,以及重复定义的问题解析

命名空间namespace,以及重复定义的问题解析名字空间是⽤来划分冲突域的,把全局名字空间划分成⼏个⼩的名字空间。

全局函数,全局变量,以及类的名字是在同⼀个全局名字空间中,有时为了防⽌命名冲突,会把这些名字放到不同的名字空间中去。

⾸先我们看⼀下名字空间的定义:1//MyLib.h⽂件2namespace MyLib{3extern int i;//记住这是变量i的声明,不是i的定义4void fun();5 }//注意名字空间不像类的定义⼀样,右⼤括号后有分号//MyLib.cpp⽂件#include<iostream>#include"MyLib.h"//包含名字空间⽣命所在的⽂件using std::cout;//这是使⽤⽣命,不是使⽤指令using std::endl;int MyLib::i=10;//这是变量i的定义,并且初始化,当然也可以不⽤初始化直接写int MyLib::i;void MyLib::fun(){cout<<i<<endl;}上述代码有⼀个特别需要注意的地⽅就是,在MyLib.h⽂件中,如果使⽤声明,⽆论函数还是变量都必须使⽤声明,如果使⽤定义,⽆论函数还是变量都要使⽤定义。

在MyLib.h中,如果⼀个使⽤声明,另⼀个使⽤定义,那么再接⼝代码分离时会出现重复定义现象,例如//A.h⽂件namespace A{int i;//变量的定义,不是声明void fun();//函数的声明,不是定义,那么函数的定义可以放在A.cpp⽂件中,此时A.cpp⽂件需要#include“A.h“,}1//A.cpp2 #include"A.h"3void A::fun(){456 }//demo.cpp#include"A.h"int main(){return0;}上述三段代码会出现问题,因为A.cpp从新定义了变量i,变量i本来已经在A.h中已经定义,⽽A.cpp中⼜包含了A.h,相当于把A.h中的所有代码复制粘贴到A.cpp中。

解决C++中重定义的方法总结

解决C++中重定义的方法总结

解决C++中重定义的⽅法总结
C++由于头⽂件重复包含了所定义的变量或者常量,编译器就会报重复定义的错误。

如果你碰见这样的问题可以考虑重下⾯⼏个⽅⾯去解决:
在出现重定义错误的头⽂件加上:
#ifndef FileName_H_
#define FileName_H_
....(头⽂件内容)
#endif
注意如果FileName_H_这个名字已经被使⽤,将会出现未定义问题(这⾥不讨论),这是你保证FileName_H_唯⼀就可以。

在出现重定义错误的头⽂件加上这⼀句:#pragma once 就可以解决(VS建⽴的类都会默认添加这⼀⾏),⽅式2与1其实是⼀样的,⼆选⼀即可(个⼈推荐使⽤⽅式1)
采⽤⽅式1或⽅式2基本上可以解决95%以上的重复定义的问题。

在开发过程中,经常会使⽤第三⽅的API,单独使⽤某⼀个API都正常,但是同时使⽤多个API的时候就会出现某些结构体重复定义的问题,此时可以按照下⾯⼏种⽅式处理:
将重复定义的struct、变量名、常量,提出到⼀个公共的.h⽂件中,然后将原⽂件中公共部分的struct、变量名、常量屏蔽或删除,同时在头⽂件中包含公共的.h⽂件。

如果三防库中,出现C风格、C++风格两种不同的struct定义⽅式,就不能按照3的⽅式解决了(⽅式3解决后编译正常,但是会出现链接问题,分析lib中的导出函数中参数与C风格参数差异)。

此时只需要将C风格⽅式的struct修改为C++风格的struct,同时更新API头⽂件中对应使⽤C风格struct位置。

c++ 结构体 重复定义

c++ 结构体 重复定义

c++ 结构体重复定义
在C++中,如果你在同一作用域内多次定义相同名称的结构体,就会导致重复定义错误。

这通常发生在头文件中,如果头文件被包含在多个源文件中,每个源文件都包含相同的结构体定义,就会引起重复定义错误。

为了避免这种错误,你可以使用头文件的预处理器指令来确保结构体只被定义一次。

这可以通过使用条件编译指令(`#ifndef`、`#define`、`#endif`)来实现,例如:
```cpp
// 在头文件中
#ifndef MY_STRUCT_H
#define MY_STRUCT_H
struct MyStruct {
// 结构体成员
int member1;
double member2;
// 其他成员...
};
#endif // MY_STRUCT_H
```
这样,当头文件第一次被包含时,`MY_STRUCT_H`未定义,结构体定义会被包括。

当头文件再次被其他文件包含时,`MY_STRUCT_H`已经被定义,预处理器将跳过结构体的重新定义。

确保你的头文件有适当的保护措施,以避免多次定义相同的结构体。

结构体重复定义

结构体重复定义

结构体重复定义在编程中,结构体是一种非常重要的数据类型。

结构体定义了一组相关联的数据项,这些数据项可以在一个变量中存储和操作。

但是,当我们在程序中定义多个相同结构体时,就会出现结构体重复定义的问题。

这个问题不仅会导致程序编译错误,还会使程序中出现一些不可预料的错误。

下面,我们将详细了解这个问题,并提供有效的解决方法。

一、什么是结构体重复定义?结构体重复定义指的是在程序中定义了多个相同的结构体。

结构体是一种自定义的数据类型,它包含了一组相关联的数据项。

当我们在程序中定义结构体时,必须要为它定义一个变量名。

如果我们在程序中定义了多个相同的结构体,那么就会出现结构体重复定义的问题。

结构体重复定义的问题常常会导致编译错误。

编译器在编译程序时,会识别出多个相同的结构体定义,从而报告出错信息。

这个问题也会使程序中出现一些未被预计的错误,例如:变量赋值错误、内存分配错误等。

因此,我们必须要注意避免结构体重复定义的问题。

二、结构体重复定义的原因1.文件包含在程序中,我们可以通过#include指令来包含一个头文件。

头文件通常包含一些函数和结构体的定义。

如果我们在多个源文件中包含了同一个头文件,就会出现结构体重复定义的问题。

例如,在两个源文件中都包含了一个名为“Student”的头文件,那么编译器就会在生成可执行文件时识别出两个相同的“Student”结构体。

这样就会导致编译错误。

2.头文件嵌套在头文件中定义的结构体可能会在其他的头文件中继续包含使用。

如果多个头文件都包含了同一个头文件,就会导致结构体重复定义的问题。

例如,在头文件A.h中定义了一个名为“Person”的结构体。

在头文件B.h和C.h中都包含了头文件A.h,那么就会出现两个相同的“Person”结构体,从而导致编译错误。

3.重复定义在程序中,我们可能会在不同的源文件中定义相同的结构体,这也会导致结构体重复定义的问题。

例如,在源文件A.c和B.c中都定义了一个名为“Employee”的结构体。

函数内联报错重复定义

函数内联报错重复定义

函数内联报错重复定义在C++编程中,函数内联(inline)是一种优化技术,可以将函数的定义直接插入到函数调用的地方,避免了函数调用的开销。

但是,在使用函数内联时,有可能会出现重复定义(redefined)的问题。

函数内联的原则是:只有在函数的定义处可见的地方才能进行内联。

也就是说,在每个文件中只能有一个函数定义,否则会出现重复定义的错误。

当我们将函数定义直接放在头文件(.h或.hpp)中时,该头文件在多个源文件中被引用时,就有可能导致函数的重复定义问题。

因为编译器在每个源文件中都会看到该函数的定义,最终链接时就会出现重复定义的错误。

下面我们来说明一下函数内联重复定义的问题及解决办法:首先,我们定义一个简单的函数在头文件中:```cpp// inline_example.h#ifndef INLINE_EXAMPLE_H#define INLINE_EXAMPLE_Hinline int add(int a, int b)return a + b;#endif然后,在两个源文件中引用该头文件:```cpp// main1.cpp#include "inline_example.h"#include <iostream>int maiint result = add(10, 20);std::cout << "Result: " << result << std::endl; return 0;``````cpp// main2.cpp#include "inline_example.h"#include <iostream>int maiint result = add(5, 7);std::cout << "Result: " << result << std::endl; return 0;如果我们将这两个源文件编译链接起来,就会出现重复定义的错误:```duplicate symbol __Z3addii in:/path/to/main1.o/path/to/main2.old: 1 duplicate symbol for architecture x86_64```这是因为编译器在编译main1.cpp和main2.cpp时都看到了add函数的定义,最终链接时就会报重复定义的错误。

《头文件导致Symbolxxxmultiplydefined重复定义问题分析和解决》

《头文件导致Symbolxxxmultiplydefined重复定义问题分析和解决》

《头⽂件导致Symbolxxxmultiplydefined重复定义问题分析和解决》1.问题main.h#ifndef _MAIN_H#define _MAIN_Hunsigned char i;#endifmain.c#include "main.h"main(){;}a.c#include "main.h"略 然后编译a.c和main.c,就会提⽰Symbol i multiply defined(by a.o and main.o)2.问题分析2.1 #ifndef不是已经预防重复编译了? #ifndef #define #endif防⽌的是“重复编译”,⽽不是“重复定义”。

重复编译可能造成重复定义,但重复定义的来源不只有重复编译。

从代码变成可执⾏的程序,需要两个步骤 编译和链接 编译开始时,将所有#include头⽂件的地⽅替换成该头⽂件的代码 在编译阶段,编译所有源⽂件成为模块,各模块中的每个变量与函数都得到了属于⾃⼰的空间 在链接阶段,各个模块被组合到⼀起 #ifndef能够防⽌在编译阶段,⼀段代码被重复编译,并且由此可以避免⼀个变量被重复定义 但它不能防⽌链接阶段,各模块中都有叫某个名字的变量,于是报链接错误:变量重复定义3.解决⽅法 不仅⽤#ifndef组合防⽌重复编译,⽽且将变量在源⽂件中定义,只在头⽂件⾥放extern声明。

这样各模块在编译的时候,就知道“有这么个变量,但它的空间不在我这⾥”,链接的时候,这个变量虽然出现在所有包含这个头⽂件的模块⾥,但只有⼀个模块是它的真⾝所在。

头文件定义函数 重复定义

头文件定义函数 重复定义

头文件定义函数重复定义
当在头文件中定义函数时,如果多个源文件包含了同一个头文件,就会导致函数的重复定义。

这通常发生在C或C++编程中。

这种情况会导致编译器在链接阶段出现错误,因为它会发现多个相同的函数定义。

为了避免函数重复定义的问题,可以采取以下几种方法:
1. 使用头文件保护符:在头文件中使用预处理指令,如
#ifndef、#define和#endif,可以防止头文件被多次包含。

例如:
#ifndef MY_HEADER_H.
#define MY_HEADER_H.
// 这里放函数声明和其他内容。

#endif.
2. 将函数定义放在源文件中,将函数的实际定义放在源文件中
而不是头文件中。

头文件只包含函数的声明,源文件包含函数的定义。

这样可以避免函数重复定义的问题。

3. 使用inline函数,对于较短的函数,可以将其声明为inline函数。

这样编译器会在每个调用点内联展开函数代码,从而避免重复定义的问题。

4. 使用static关键字,在C语言中,可以使用static关键字限制函数的作用域,使其只在当前源文件中可见,避免了函数在多个源文件中重复定义的问题。

总之,避免函数重复定义的关键在于良好的头文件管理和合理的函数定义方式。

通过合理地组织代码结构并采取上述方法,可以有效地解决函数重复定义的问题。

multiple definition条件编译

multiple definition条件编译

multiple definition条件编译多重定义(Multiple Definition)指的是同一个标识符在同一翻译单位中多次定义的情况,这会导致编译时出现错误或者运行时出现未定义行为。

条件编译(Conditional Compilation)指的是根据预处理器定义的条件编译指令,控制源代码的编译。

通过使用条件编译指令,可以在相同代码文件中实现针对不同操作系统、不同平台或者不同编译器的不同行为。

在条件编译中,可以使用 #ifdef、#ifndef、#elif、#else、#endif 等众多指令来控制代码的编译,这些指令一般在头文件中使用。

多重定义和条件编译在C/C++中经常同时出现,下面将结合具体案例来讲解在C/C++中如何正确使用条件编译解决多重定义问题。

一、没有使用条件编译引发的多重定义问题假设有两个源文件 A.c 和 B.c,其中都包含了头文件test.h,test.h 文件中定义了一个全局变量 g_test。

test.h 文件中的内容如下:``` // test.h #ifndef _TEST_H_ #define _TEST_H_ int g_test;#endif ```A.c 文件的内容如下:``` // A.c #include "test.h" int main(){ g_test = 1; return 0; } ```B.c 文件的内容如下:``` // B.c #include "test.h" void foo(){ g_test = 2; } ```在没有使用条件编译的情况下,当我们尝试编译这两个源文件时,就会发生多重定义错误,命令行输出如下:``` > gcc A.c B.c -o test/tmp/ccNYGZq3.o:(.bss+0x0): multiple definition of `g_test' /tmp/ccEAhsvY.o:(.bss+0x0): first defined here collect2: error: ld returned 1 exit status ```这个错误的原因是因为在 A.c 和 B.c 中都包含了test.h 头文件,其中定义了全局变量 g_test,编译器并不知道应该将其链接到哪个文件中,导致了重复定义。

C语言常见错误代码释义

C语言常见错误代码释义

C语言常见错误代码释义错误代码及错误信息错误释义error 1: Out of memory 内存溢出error 2: Identifier expected 缺标识符error 3: Unknown identifier 未定义的标识符error 4: Duplicate identifier 重复定义的标识符error 5: Syntax error 语法错误error 6: Error in real constant 实型常量错误error 7: Error in integer constant 整型常量错误error 8: String constant exceeds line 字符串常量超过一行error 10: Unexpected end of file 文件非正常结束error 11: Line too long 行太长error 12: Type identifier expected 未定义的类型标识符error 13: Too many open files 打开文件太多error 14: Invalid file name 无效的文件名error 15: File not found 文件未找到error 16: Disk full 磁盘满error 17: Invalid compiler directive 无效的编译命令error 18: Too many files 文件太多error 19: Undefined type in pointer def 指针定义中未定义类型error 20: Variable identifier expected 缺变量标识符error 21: Error in type 类型错误error 22: Structure too large 结构类型太长error 23: Set base type out of range 集合基类型越界error 24: File components may not be files or objectsfile分量不能是文件或对象error 25: Invalid string length 无效的字符串长度error 26: Type mismatch 类型不匹配error 27:error 27:Invalid subrange base type 无效的子界基类型error 28:Lower bound greater than upper bound 下界超过上界error 29:Ordinal type expected 缺有序类型error 30:Integer constant expected 缺整型常量error 31:Constant expected 缺常量error 32:Integer or real constant expected 缺整型或实型常量error 33:Pointer Type identifier expected 缺指针类型标识符error 34:Invalid function result type 无效的函数结果类型error 35:Label identifier expected 缺标号标识符error 36:BEGIN expected 缺BEGINerror 37:END expected 缺ENDerror 38:Integer expression expected 缺整型表达式error 39:Ordinal expression expected 缺有序类型表达式error 40:Boolean expression expected 缺布尔表达式error 41:Operand types do not match 操作数类型不匹配error 42:Error in expression 表达式错误error 43:Illegal assignment 非法赋值error 44:Field identifier expected 缺域标识符error 45:Object file too large 目标文件太大error 46:Undefined external 未定义的外部过程与函数error 47:Invalid object file record 无效的OBJ文件格式error 48:Code segment too large 代码段太长error 49:Data segment too large 数据段太长error 50:DO expected 缺DOerror 51:Invalid PUBLIC definition 无效的PUBLIC定义error 52:Invalid EXTRN definition 无效的EXTRN定义error 53: Too many EXTRN definitions 太多的EXTRN定义error 54:OF expected 缺OFerror 55:INTERFACE expected 缺INTERFACEerror 56:Invalid relocatable reference 无效的可重定位引用error 57:THEN expected 缺THENerror 58:TO or DOWNTO expected 缺TO或DOWNTOerror 59:Undefined forward 提前引用未经定义的说明error 61:Invalid typecast 无效的类型转换error 62:Division by zero 被零除error 63:Invalid file type 无效的文件类型error 64:Cannot read or write variables of this type 不能读写此类型变量error 65:Pointer variable expected 缺指针类型变量error 66:String variable expected 缺字符串变量error 67:String expression expected 缺字符串表达式error 68:Circular unit reference 单元UNIT部件循环引用error 69:Unit name mismatch 单元名不匹配error 70:Unit version mismatch 单元版本不匹配error 71:Internal stack overflow 内部堆栈溢出error 72:Unit file format error 单元文件格式错误error 73:IMPLEMENTATION expected 缺IMPLEMENTATIONerror 74:Constant and case types do not match 常量和CASE类型不匹配error 75:Record or object variable expected 缺记录或对象变量error 76:Constant out of range 常量越界error 77:File variable expected 缺文件变量error 78:Pointer expression expected 缺指针表达式error 79:Integer or real expression expected 缺整型或实型表达式error 80:Label not within current block 标号不在当前块内error 81:Label already defined 标号已定义error 82:Undefined label in preceding statement part 在前面未定义标号error 83:Invalid @ argument 无效的@参数error 84:UNIT expected 缺UNITerror 85: ";" expected 缺“;”error 86:":" expected 缺“:”error 87:"," expected 缺“,”error 88:"(" expected 缺“(”error 89:")" expected 缺“)”error 90:"=" expected 缺“=”error 91:":=" expected 缺“:=”error 92:"[" or "(." Expected 缺“[”或“(.”error 93: "]" or ".)" expected 缺“]”或“.)”error 94:"." expected 缺“.”error 95: ".." expected 缺“..”error 96:Too many variables 变量太多error 97:Invalid FOR control variable 无效的FOR循环控制变量error 98:Integer variable expected 缺整型变量error 99:Files and procedure types are not allowed here 该处不允许文件和过程类型error 100:String length mismatch 字符串长度不匹配error 101:Invalid ordering of fields 无效域顺序error 102:String constant expected 缺字符串常量error 103:Integer or real variable expected 缺整型或实型变量error 104:Ordinal variable expected 缺有序类型变量error 105:INLINE error INLINE错误error 106:Character expression expected 缺字符表达式error 107:Too many relocation items 重定位项太多error 108:Overflow in arithmetic operation 算术运算溢出error 112:CASE constant out of range CASE常量越界error 113:Error in statement 表达式错误error 114:Cannot call an interrupt procedure 不能调用中断过程error 116:Must be in 8087 mode to compile this 必须在8087模式编译error 117:T arget address not found 找不到目标地址error 118:Include files are not allowed here 该处不允许INCLUDE文件error 119:No inherited methods are accessible here 该处继承方法不可访问error 121:Invalid qualifier 无效的限定符error 122:Invalid variable reference 无效的变量引用error 123:Too many symbols 符号太多error 124:Statement part too large 语句体太长error 126:Files must be var parameters 文件必须是变量形参error 127:Too many conditional symbols 条件符号太多error 128:Misplaced conditional directive 条件指令错位error 129:ENDIF directive missing 缺ENDIF指令error 130:Error in initial conditional defines 初始条件定义错误error 131:Header does not match previous definition 和前面定义的过程或函数不匹配error 133:Cannot evaluate this expression 不能计算该表达式error 134:Expression incorrectly terminated 表达式错误结束error 135:Invalid format specifier 无效格式说明符error 136:Invalid indirect reference 无效的间接引用error 137:Structured variables are not allowed here 该处不允许结构变量error 138:Cannot evaluate without System unit 没有System单元不能计算error 139:Cannot access this symbol 不能存取符号error 140:Invalid floating point operation 无效的符号运算error 141:Cannot compile overlays to memory 不能编译覆盖模块至内存error 142:Pointer or procedural variable expected 缺指针或过程变量error 143:Invalid procedure or function reference 无效的过程或函数调用error 144:Cannot overlay this unit 不能覆盖该单元error 146:File access denied 不允许文件访问error 147:Object type expected 缺对象类型error 148:Local object types are not allowed 不允许局部对象类型error 149:VIRTUAL expected 缺VIRTUALerror 150: Method identifier expected 缺方法标识符error 151:Virtual constructors are not allowed 不允许虚构造函数error 152:Constructor identifier expected 缺构造函数标识符error 153:Destructor identifier expected 缺析构函数标识符error 154:Fail only allowed within constructors 只能在构造函数内使用Fail标准过程error 155:Invalid combination of opcode and operands 操作数与操作符无效组合error 156:Memory reference expected 缺内存引用指针error 157:Cannot add or subtract relocatable symbols 不能加减可重定位符号error 158:Invalid register combination 无效寄存器组合error 159:286/287 instructions are not enabled 未激活286/287指令error 160:Invalid symbol reference 无效符号指针error 161:Code generation error 代码生成错误error 162:ASM expected 缺ASMerror 166:Procedure or function identifier expected 缺过程或函数标识符error 167:Cannot export this symbol 不能输出该符号error 168:Duplicate export name 外部文件名重复error 169:Executable file header toerror 170:Too many segments 段太多。

对于单片机中重复定义的问题

对于单片机中重复定义的问题

做了。 对于大一点的程序,有很多 c 文件和头文件,这个时候全局变量就必 须在头文件中声明(不需要初始化),然后在一个 c 文件中定义(该初始化的要 初始化)。如果在头文件中定义,则编译的时候会出现重复定义的错误。如果 只有头文件中声明就会出现没有定义有警告。 *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: K MODULE: 222.obj (222)出现上述错误则 是因为变量 声 明不用初始化),再在某一个你要调用该变量的 c 文件的程序之前再定义(注 意第一个调用的 c 文件要负责附带初始化该变量,其他调用的 c 文件就不需 要初始化过程啦)一下就可以了。
对于单片机中重复定义的问题
前几天调试 ZigBee 程序时,因为要用到全局变量,所以在一个全局文件 定义了两个全局变量,如下: #ifndef _TC77_H_#define _TC77_H_ BYTE GetTC77String( char *buffer ); unsigned char WATER_flag = 1;unsigned char LIGHT_flag = 1; #endif 不过编译后却出现这样的错误: Copyright (c) 2009 Microchip Technology Inc.Error - could not find definition of symbol ‘LIGHT_flag’ in file ‘objects/TC77.o’.Errors : 1 可能是因为在两个文件里同时调用了 tc77.h 这个文件的缘故,不过我想不 通的是既然有宏条件定义,为什幺还会出现重复定义的现象呢? 后来在网上查了一下,把定义改成如下形式就好了: #ifndef _TC77_H_#define _TC77_H_

multiple definition of 函数

multiple definition of 函数

multiple definition of 函数多重定义是编程中常见的问题之一,尤其是在大型项目中,由于代码量大、多人协作等原因,很容易出现同名函数的情况。

本文将从以下几个方面探讨多重定义的问题,包括其原因、解决方法以及对程序设计的启示等。

一、多重定义的原因多重定义通常是由于以下几个原因造成的:1.文件包含在C/C++等编程语言中,可以通过#include指令将其他文件中的代码引入到当前文件中。

如果多个文件都包含了同一个文件,而该文件中又定义了同名函数,就会出现多重定义的情况。

2.编译器链接编译器在编译过程中会将多个源文件(.c或.cpp)编译成目标文件(.o或.obj),然后将这些目标文件链接成一个可执行文件。

如果多个源文件中定义了同名函数,编译器在链接时就会出现冲突。

3.宏定义宏定义是预处理指令的一种,可以将一些常用的代码片段定义为宏,以便在代码中多次使用。

如果多个宏定义了同名函数,也会出现多重定义的情况。

以上三种原因是多重定义的主要来源,当然还有其他一些情况,比如使用静态库时出现同名函数等。

二、解决多重定义的方法针对不同的多重定义原因,解决方法也不同。

下面分别介绍几种常用的解决方法:1.使用头文件保护头文件保护是一种简单有效的方法,可以避免文件包含导致的多重定义问题。

在头文件中加入如下代码即可:#ifndef _HEADER_FILE_NAME_H#define _HEADER_FILE_NAME_H//头文件内容#endif其中_HEADER_FILE_NAME_H为头文件的名称,如果该头文件已经被包含过,则不会再次包含,从而避免了多重定义问题。

2.使用静态函数静态函数是指只在当前文件中可见的函数,不会被其他文件调用。

如果在多个文件中都定义了同名函数,可以将其改为静态函数,从而避免冲突。

具体做法是在函数定义前加上static关键字,如下所示: static int add(int a, int b){return a + b;}这样就可以避免与其他文件中同名函数的冲突。

c multiple definition 结构

c multiple definition 结构

c multiple definition 结构
在C语言中,当一个符号有多个定义时,就会出现"multiple definition"错误。

这种错误通常发生在以下情况下:
1. 在多个源文件中定义了相同的全局变量或函数。

比如,如果在文件A.c和文件B.c中都定义了同名的全局变量或函数,编
译器就会报"multiple definition"错误。

2. 在同一个源文件中多次定义了相同的全局变量或函数。

比如,如果在文件A.c中多次定义了同名的全局变量或函数,编译器
也会报"multiple definition"错误。

为了解决"multiple definition"错误,可以采取以下措施:
1. 使用extern关键字声明全局变量或函数,而不是在多个源文件中定义它们。

在其中一个源文件中定义变量或函数,然后在其他源文件中使用extern关键字声明即可。

2. 将全局变量或函数定义放在一个单独的源文件中,并在其他源文件中使用extern关键字声明它们。

然后在链接时将所有源文件一起编译。

3. 使用头文件来声明全局变量或函数,并在需要使用它们的源文件中包含该头文件。

总之,在C语言中避免"multiple definition"错误的方法是避免
在多个源文件中多次定义相同的全局变量或函数,并使用合适的声明和定义方式。

3_重复定义(MULTIPLE PUBLIC DEFINITIONS )

3_重复定义(MULTIPLE PUBLIC DEFINITIONS )

<涉及到外部变量的声明>(不是定义,因为不能赋值)c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下。

对于比较小的程序,一般只有一个c文件和一个头文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。

如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量i进行声明,在c 文件的程序之前必须加上int i进行定义。

extern int i=0;这一句声明和定义都做了。

对于大一点的程序,有很多c文件和头文件,这个时候全局变量就必须在头文件中声明(不需要初始化),然后在一个c文件中定义(该初始化的要初始化)。

如果在头文件中定义,则编译的时候会出现重复定义的错误。

如果只有头文件中声明就会出现没有定义有警告。

*** ERROR L104: MULTIPLE PUBLIC DEFINITIONSSYMBOL: KMODULE: 222.obj (222)出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)首先纠正你的一个错误,extern是用来声明变量而不是定义变量的当你需要在一个c语言文件中使用另外一个c语言文件中定义的变量时就需要加上extern来声明,这样编译器就知道这个变量是在别的文件中定义的。

比如:你在foo.c中定义了一个全局变量int a=10,你在fff.c中想使用这个变量a,那么你就需要在使用之前在fff.c中用extern声明这个变量:extern int a;1.extern的作用extern有两个作用,第一个,当它与"C"一起连用时,如: extern "C" void fun(int a, int b); 则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的, C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样),为什么这么做呢,因为C++支持函数的重载啊,在这里不去过多的论述这个问题,如果你有兴趣可以去网上搜索,相信你可以得到满意的解释!当extern不与"C"在一起修饰变量或函数时,如在头文件中: extern int g_Int; 它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块或其他模块中使用,记住它是一个声明不是定义!也就是说B模块(编译单元)要是引用模块(编译单元)A中定义的全局变量或函数时,它只要包含A模块的头文件即可, 在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在连接时从模块A生成的目标代码中找到此函数。

C---C语言重复定义的问题

C---C语言重复定义的问题

C---C语⾔重复定义的问题⼤纲头⽂件的作⽤驱动⽂件和头⽂件中该存放什么内容如何防⽌重复定义头⽂件使⽤案例1.头⽂件的作⽤(1)为其他驱动⽂件(.c)或者头⽂件(.h)调⽤相关函数、结构体、数组、全局变量等(2)最常⽤的就是调⽤API接⼝(openCV、QT中的相关模板)2. 驱动⽂件和头⽂件中该存放什么内容?驱动⽂件(.h)存放对外调⽤的函数,数组、结构体、变量等申明(全局变量extern)头⽂件(.c)存放定义函数、数组、结构体、变量的初始化等等,static函数或变量。

注:⼀般不要在头⽂件中定义变量、函数、类,否者容易产⽣重复定义3.如何防⽌重复定义重复定义是调⽤别⼈的库函数时变量被重新申明。

如:在a.h 中申明变量 extern int a;在b.h 中申明变量 extern int a;这时候:在c.c中调⽤ a.h 和 b.h ,就会出现 xxxx has been defined .头⽂件使⽤案例(1):不涉及重复定义//a.c//#include<stdio.h>void print(void){printf(“test\n”);}//a.hextern void print(void);//b.c#include<a.h>main(){print();}after compiled, print test.头⽂件使⽤案例(2):涉及重复定义我们在使⽤头⽂件定义时候,如定义结构体在头⽂件中定义,在头⽂件中申明全局或者在驱动⽂件中定义,在头⽂件中申明全局变量。

本案例定义结构体变量,然后初始化结构体,然后在主函数中调⽤结构体函数实现相应功能。

//1.struct.h#ifndef __a_H_#define __a_H_typedef struct{unsigned char i;unsigned char u;unsigned char v;} check;#endif//2. xxx.c初始化结构体#include<struct.h>void initalstruct(check* AAA){AAA->i =3;AAA->u =4;AAA->v =5;}// xxx.hextern void initalstruct(check* AAA);#include<stdio.h>#include<struct.h> //定义结构体#include<xxx.h> //调⽤结构体初始化函数int main(){check check1;initalstruct(&check1);printf(“%d\n”,check1.i );}拖延让你失去很多,并且那些是再也回不去的昨天。

【转】利用匿名namespace解决C++中重复定义的问题

【转】利用匿名namespace解决C++中重复定义的问题

【转】利⽤匿名namespace解决C++中重复定义的问题⽬录原⽂:利⽤匿名namespace解决C++中重复定义的问题今天写代码的时候⼜碰到了C++中多编译单元导致重复定义(multi definition)的链接问题。

其实这个问题以前也碰到过⼏次,急着编译出代码也没有去深究背后的⼀些知识。

今天系统的看了⼀些资料,算是把这个问题彻底搞清楚了。

这⾥做下简单总结吧:C++中有由于模版分离编译等问题,导致常常需要在头⽂件加⼊变量定义或者函数定义的代码,从⽽在链接多编译单元时导致multi-definition重复定义的问题。

传统C语⾔中的static关键在C++中对于类的成员有其他的语义,导致其功能的局限性。

在C++中建议使⽤匿名namespace类实现将⼀个函数或者变量的定义局限在⼀个编译单元内,避免multi-definition 的问题。

在C++中的,由于引⼊了⾯向对象的概念,导致了有时候在头⽂件中不得不加⼊函数实现或者变量定义的代码。

⽐如在⼤部分编译器上不⽀持模版分离编译,导致很多模板类的实现只有放在头⽂件中,像boost等库都⼤量采⽤了hpp这种格式实现完全头⽂件化的库。

但是这种⽅法经常会导致⼀个问题就是multi-definition重复定义,在较⼤型的⼯程中往往会采⽤多编译单元的形式⽣成多个.o⽂件,然后再⽤ld链接⽣成可执⾏⽂件。

如果多个.o中都include了同⼀个hpp⽂件,⽽该hpp⽂件⼜包含了全局变量,类的静态成员等⼀些变量的定义,那么就会导致gcc的multi-definition报错。

在传统的C程序中可以通过static申明⼀个变量或者函数不⽣成全局符号来解决这个问题,但是C++中static关键字对于类的成员有了其他语义。

因此C++中建议使⽤匿名namespace来替代static避免multi-definition的问题。

看如下⼀个例⼦:----------- test.hpp----------#include <string>classA{public:staticstd::string y;};std::string A::y = std::string();----------- test_comm.cpp----------#include "test.hpp"voidfunc() { }----------- test_main.cpp----------#include "test.hpp"voidfunc();intmain(intargc, char*argv){func();}我们在g++上编译就会出现如下错误:leoxiang@SEC38_64_sles10:~$ g++ -c test_comm.cppleoxiang@SEC38_64_sles10:~$ g++ -c test_main.cppleoxiang@SEC38_64_sles10:~$ g++ -o testtest_comm.o test_main.otest_main.o:(.bss+0x0): multiple definition of `A::y'test_comm.o:(.bss+0x0): first defined herecollect2: ld returned 1 exitstatus下⾯通过匿名namespace解决这个问题,只需要把test.hpp的实现⽤匿名namespace包围即可避免重复定义的问题:----------- test.hpp----------#include <string>namespace{classA{public:staticstd::string y;};std::string A::y = std::string();}实际上匿名namespace的作⽤是把其中的变量都放在了⼀个随机名字空间中,并且保证改名字空间在多个编译单元中是唯⼀的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

<涉及到外部变量的声明>(不是定义,因为不能赋值)c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下。

对于比较小的程序,一般只有一个c文件和一个头文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。

如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量i进行声明,在c 文件的程序之前必须加上int i进行定义。

extern int i=0;这一句声明和定义都做了。

对于大一点的程序,有很多c文件和头文件,这个时候全局变量就必须在头文件中声明(不需要初始化),然后在一个c文件中定义(该初始化的要初始化)。

如果在头文件中定义,则编译的时候会出现重复定义的错误。

如果只有头文件中声明就会出现没有定义有警告。

*** ERROR L104: MULTIPLE PUBLIC DEFINITIONSSYMBOL: KMODULE: 222.obj (222)出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)首先纠正你的一个错误,extern是用来声明变量而不是定义变量的当你需要在一个c语言文件中使用另外一个c语言文件中定义的变量时就需要加上extern来声明,这样编译器就知道这个变量是在别的文件中定义的。

比如:你在foo.c中定义了一个全局变量int a=10,你在fff.c中想使用这个变量a,那么你就需要在使用之前在fff.c中用extern声明这个变量:extern int a;1.extern的作用extern有两个作用,第一个,当它与"C"一起连用时,如: extern "C" void fun(int a, int b); 则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的, C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样),为什么这么做呢,因为C++支持函数的重载啊,在这里不去过多的论述这个问题,如果你有兴趣可以去网上搜索,相信你可以得到满意的解释!当extern不与"C"在一起修饰变量或函数时,如在头文件中: extern int g_Int; 它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块或其他模块中使用,记住它是一个声明不是定义!也就是说B模块(编译单元)要是引用模块(编译单元)A中定义的全局变量或函数时,它只要包含A模块的头文件即可, 在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在连接时从模块A生成的目标代码中找到此函数。

2.实例:以上已经说了extern的作用,下面我们来举个例子,如:在test1.h中有下列声明:#ifndef TEST1H#define TEST1Hextern char g_str[]; // 声明全局变量g_strvoid fun1();#endif在test1.cpp中#include "test1.h"char g_str[] = "123456"; // 定义全局变量g_strvoid fun1(){cout << g_str << endl;}以上是test1模块,它的编译和连接都可以通过,如果我们还有test2模块也想使用g_str,只需要在原文件中引用就可以了#include "test1.h"void fun2(){cout << g_str << endl;}以上test1和test2可以同时编译连接通过,如果你感兴趣的话可以用ultraEdit打开test1.obj,你可以在里面着"123456"这个字符串,但是你却不能在test2.obj里面找到,这是因为g_str是整个工程的全局变量,在内存中只存在一份, test2.obj这个编译单元不需要再有一份了,不然会在连接时报告重复定义这个错误!有些人喜欢把全局变量的声明和定义放在一起,这样可以防止忘记了定义,如把上面test1.h改为extern char g_str[] = "123456"; // 这个时候相当于没有extern 然后把test1.cpp中的g_str的定义去掉,这个时候再编译连接test1和test2两个模块时,会报连接错误,这是因为你把全局变量 g_str的定义放在了头文件之后,test1.cpp 这个模块包含了test1.h所以定义了一次g_str,而 test2.cpp也包含了test1.h所以再一次定义了g_str, 这个时候连接器在连接test1和test2时发现两个g_str。

如果你非要把g_str的定义放在test1.h中的话,那么就把test2的代码中#include "test1.h"去掉换成:extern char g_str[];void fun2(){cout << g_str << endl;}这个时候编译器就知道g_str是引自于外部的一个编译模块了,不会在本模块中再重复定义一个出来,但是我想说这样做非常糟糕,因为你由于无法在 test2.cpp中使用#include "test1.h", 那么test1.h中声明的其他函数你也无法使用了,除非也用都用extern修饰,这样的话你光声明的函数就要一大串,而且头文件的作用就是要给外部提供接口使用的,所以请记住,只在头文件中做声明,真理总是这么简单。

2.用static修饰的全局变量首先,我要告诉你static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变量;其次,static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它,如:test1.h:#ifndef TEST1H#define TEST1Hstatic char g_str[] = "123456";void fun1();#endiftest1.cpp:#include "test1.h"void fun1(){cout << g_str << endl;}test2.cpp#include "test1.h"void fun2(){}以上两个编译单元可以连接成功, 当你打开test1.obj时,你可以在它里面找到字符串"123456", 同时你也可以在test2.obj中找到它们,它们之所以可以连接成功而没有报重复定义的错误是因为虽然它们有相同的内容,但是存储的物理地址并不一样,就像是两个不同变量赋了相同的值一样,而这两个变量分别作用于它们各自的编译单元。

也许你比较较真,自己偷偷的跟踪调试上面的代码,结果你发现两个编译单元(test1, test2)的g_str的内存地址相同,于是你下结论static修饰的变量也可以作用于其他模块,但是我要告诉你,那是你的编译器在欺骗你,大多数编译器都对代码都有优化功能,以达到生成的目标程序更节省内存,执行效率更高,当编译器在连接各个编译单元的时候,它会把相同内容的内存只拷贝一份,比如上面的"123456", 位于两个编译单元中的变量都是同样的内容,那么在连接的时候它在内存中就只会存在一份了,如果你把上面的代码改成下面的样子,你马上就可以拆穿编译器的谎言:test1.cpp:#include "test1.h"void fun1(){g_str[0] = 'a';cout << g_str << endl;}test2.cpp#include "test1.h"void fun2(){}void main(){fun1(); // a23456fun2(); // 123456}这个时候你在跟踪代码时,就会发现两个编译单元中的g_str地址并不相同,因为你在一处修改了它,所以编译器被强行的恢复内存的原貌,在内存中存在了两份拷贝给两个模块中的变量使用。

正是因为static有以上的特性,所以一般定义static全局变量时,都把它放在原文件中而不是头文件,这样就不会给其他模块造成不必要的信息污染,同样记住这个原则吧!3 const修饰的全局常量const修饰的全局常量用途很广,比如软件中的错误信息字符串都是用全局常量来定义的。

const修饰的全局常量据有跟static相同的特性,即它们只能作用于本编译模块中,但是const可以与extern连用来声明该常量可以作用于其他编译模块中, 如extern const char g_str[];然后在原文件中别忘了定义:const char g_str[] = "123456";所以当const单独使用时它就与static相同,而当与extern一起合作的时候,它的特性就跟extern的一样了!所以对const我没有什么可以过多的描述,我只是想提醒你,const char* g_str = "123456" 与 const char g_str[] = "123465"是不同的,前面那个const修饰的是char * 而不是g_str,它的g_str并不是常量,它被看做是一个定义了的全局变量(可以被其他编译单元使用),所以如果你像让char *g_str遵守const的全局常量的规则,最好这么定义const char* const g_str="123456".。

相关文档
最新文档