为何“ const char * lp ='abc'"是外部但是“const int n = 1”内部? [英] why " const char * lp = 'abc' " is external but "const int n = 1" is internal?

查看:58
本文介绍了为何“ const char * lp ='abc'"是外部但是“const int n = 1”内部?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有const char * lp ='abc'的头文件;并被包含多次(即位于多个文件中)。但是vs编译器抱怨已在xxx.obj中定义(如这个。)



但我知道const var默认是内部的。我已经尝试过const int n = 1在同一个头文件中是可以的。



为什么不const char * lp?提前谢谢。

I have a header file with " const char * lp = 'abc' ";and be included multi-times(i.e located more than 1 file).But the vs compiler complains "have defined in xxx.obj"(like this.)

But I know that the const var is internal by default. And I have tried that the "const int n =1" is OK within the same header file.

Why not " const char * lp " ? thanks in advance.

推荐答案

这是一个快速的线索,其他人似乎错过了...当有人抱怨obj文件时,这不是编译问题,这是链接器有一个问题。



你是正确的 const 意味着内部联系 - 即变量的名称不应该从它定义的转换单元中转义。如果你在两个翻译单元中定义了两个 const 具有相同名称的对象,那么一切都很好,并且工作正常。正如您已经注意到它与 const int 一起使用,那么您想要使用的指针类型有什么问题?



问题在于你写的时候:



Here's a quick clue which the others seem to have missed... when something is complaining about an obj file it's not the compilation that's the problem, it's the linker that's having a whinge.

You're correct that const implies internal linkage - i.e. the name of the variable shouldn't escape from the translation unit it's defined in. If you define two const objects with the same name in two translation units everything is hunky dory and works fine. As you've noticed it works with const ints, so what's wrong with the pointer type you want to use?

The problem is that that when you write:

const char *lp = "Urgle...";





lp 不是常数。您可以修改 lp 到您心中的内容 - 您不能做的是修改 * lp 。如果你真的想让lp成为常数,那么你可以在不同的翻译单元中使用相同的名称,你必须使指针本身保持不变:





lp isn't constant. You can modify lp to your heart's content - what you can't do is modify *lp. If you really want to make lp a constant so you can have things with the same name in different translation units you have to make the pointer itself a constant:

const char * const lp = "Urgle...";





就可以了。



虽然它不是一本关于C ++的书,但我推荐Peter Van Der Linden的书专家C编程:Deep C Secrets ,用于解释和编写C和C ++中的声明。 C ++与它如何对待const有点不同,但它仍然可以帮助你了解C ++的声明语法。



编辑:编辑标点符号并且有点突出我错过了



will do the trick.

While it's not a book on C++ I'd recommend Peter Van Der Linden's book Expert C Programming: Deep C Secrets for how to decode and write declarations in C and C++. C++ is a bit different as to how it treats const but it'l still help you get your brain around C++'s declaration syntax.

Edited for punctuation and a bit of highlighting I missed


你所知道的是错的。谁告诉你的?你显然不明白你在说什么。



忘记包含文件一分钟。包含在编译之前。想象一下,他们都被他们的文本所取代(这是在编译之前真正发生的事情)。然后你将只有CPP文件。每个都分别编译成一些目标文件;您将拥有与CPP文件一样多的目标文件。然后通过链接将所有目标文件创建为可执行代码。因此,每个CPP文件都被编译成一个单独的编译单元



如何在编译单元中使用变量或常量。对于函数和类型,它很容易,但是在定义点和常量处初始化的变量如何? 技巧是:有声明定义(对于函数也是如此,但我们讨论的是变量和常量)。当初始化变量或常量时,它必须是一个定义;它定义了真正存在的对象。这应该只在编译单元中完成一次。你自己思考:如果你所有包括的效果,你有两个不同的声明,它应该编译吗?例如:

What you "know" is wrong. Who told you that? You apparently don't understand what you are talking about.

Forget for a minute about include files. The are included before compilation. Imagine that they are all substituted with their texts (this is what really happens before compilation). Then you will have only CPP files. Each one is compiled separately into some object file; you will have as many object files as CPP files. Then the executable code is created by linking together all object files. So, each CPP file is compiled into a separate compilation unit.

How one can use variables or constants across compilation units. With functions and types, it's easy, but how about the variables initialized at the point of definitions, and constants? The "trick" is: there are declarations and definitions (for functions, too, but we are talking about variables and constants). When a variable or constant is initialized, it has to be a definition; it defines really existing object. This should be done only once in a compilation unit. Think by yourself: if, by the effect of all you "includes", you have two different declaration, should it compile? For example:
// won't compile:
const char * lp = "abc";
const char * lp = "cde";



当然,不是。编译器如何知道你真正需要什么值abc或cde? (注意:这不是赋值;这是初始化!)如果您理解,如果使用相同的值初始化有什么区别。这也不会编译:


Of course, not. How a compiler would "know" what value do you really need "abc" or "cde"? (Note: this is not assignment; this is initialization!) If you understand that, what's the difference if you initialize with the same value. This won't compile, too:

// won't compile:
const char * lp = "abc";
const char * lp = "abc";



真正的原因是:你不能有两个真正存在的同名对象,因为当你在代码中的任何地方提到名字时,编译器不会知道链接哪一个。



与这种情况相反,你可以有一个或多个使用单词 extern 声明同一个对象:

http://msdn.microsoft.com/en-us/library/0603949d.aspx [ ^ ]。



请注意,这并不代表定义应该在一个单独的编译单元中。它只说它有静态持续时间。如果编译器在当前C ++文件(相同的编译单元)的范围内找不到静态定义,则它会在目标文件中按名称创建引用,然后链接器将尝试在其他目标文件中查找该定义。 />


-SA


The real reason is: you cannot have two really existing objects with the same name, because the compiler would not "know" which one to link when you mention the name anywhere in code.

In contrast to this situation, you can have one or more declarations of the same object using the word extern:
http://msdn.microsoft.com/en-us/library/0603949d.aspx[^].

Note that it does not mean that the definition should be in a separate compilation unit. It only say that it has the static duration. If the compiler cannot find the static definition in the scope of the current C++ file (same compilation unit), it creates a reference by name in the object file, and then the linker will try to find the definition in other object files.

—SA


这篇关于为何“ const char * lp ='abc'"是外部但是“const int n = 1”内部?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆