将静态数组定义为 C 或 C++ 源文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4645458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Defining a static array into a C or C++ source file
提问by VansFannel
I know this is a question that every programmer should know, but I do not know. Long time no C programming and I've forgotten a lot of things.
我知道这是每个程序员都应该知道的问题,但我不知道。很长时间没有 C 编程,我已经忘记了很多事情。
My question is:
我的问题是:
I have three huge static arrays defined inside a header file. Someone told me that It's much better to declare them as extern
in the header file, and define them in a single C or C++ source file.
我在头文件中定义了三个巨大的静态数组。有人告诉我,最好extern
在头文件中声明它们,并在单个 C 或 C++ 源文件中定义它们。
How can I do that?
我怎样才能做到这一点?
Here is my header file:
这是我的头文件:
#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_
#define NUM_TEMPLE_OBJECT_VERTEX 10818
static const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
static const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
static const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
#endif
If a use a C++ source file, may I need to define a class?
如果使用 C++ 源文件,我是否需要定义一个类?
UPDATE:
I think the problem is:
Every source file in which those headers are included (even indirectly) will generate its own definition for those static arrays. There's no guarantee that the compiler/linker will optimize them into a single definition, even in source files where they're unused. In fact, in many cases the compiler cannot optimize them away. This could result in your static data consuming a lot of disk space, and possibly runtime memory as well.
更新:
我认为问题是:
包含这些头文件的每个源文件(甚至是间接的)都会为这些静态数组生成自己的定义。无法保证编译器/链接器会将它们优化为单个定义,即使在未使用它们的源文件中也是如此。事实上,在许多情况下,编译器无法将它们优化掉。这可能会导致您的静态数据消耗大量磁盘空间,并且可能还会消耗运行时内存。
Thank you.
谢谢你。
回答by Oystein
static
and extern
at the same time makes no sense. static
at file scope makes the array inaccessible by other files, while extern
tells the compiler that your array is defined somewhere else.
static
而extern
在同一时间是没有意义的。static
在文件范围内使其他文件无法访问该数组,同时extern
告诉编译器您的数组是在其他地方定义的。
You can do what 321008 suggests, except that you don't declare your arrays staticwhich is illegal C and C++. That gives you three global variables that you can use wherever the header file is included.
您可以按照 321008 的建议进行操作,只是您不将数组声明为 static,这是非法的 C 和 C++。这为您提供了三个全局变量,您可以在包含头文件的任何位置使用它们。
For example like this:
例如像这样:
// .h file:
extern const float TEMPLEVertices[];
// .cpp (or .c) file:
const float TEMPLEVertices[] = { 1.0, 2.0, 5.6 /* or whatever*/ };
Or you can do what fortran suggests, but that will give you file-scope access only, not global variables.
或者您可以按照 fortran 的建议进行操作,但这只会为您提供文件范围的访问权限,而不是全局变量。
You do notin any way have to define a class if you use a C++ source file. Unlike Java, C++ does not force you into an object oriented design (whether or not that is good can probably be discussed, but anyway).
如果使用 C++ 源文件,则不必以任何方式定义类。与 Java 不同,C++ 不会强迫您采用面向对象的设计(可能会讨论这是否好,但无论如何)。
EDIT: As for your question update, that is because you define them as static
. If you only want global variables, you should not do that, but instead keep one single definition (const float
) and reference it with extern
, as per my example above.
编辑:至于您的问题更新,那是因为您将它们定义为static
. 如果您只需要全局变量,则不应这样做,而应保留一个定义 ( const float
) 并使用 引用它extern
,就像我上面的示例一样。
回答by fortran
I once saw in the Quake2 source code a funny "trick", that in fact was just an unusual way of using an include:
我曾经在 Quake2 源代码中看到一个有趣的“技巧”,实际上这只是一种使用包含的不寻常方式:
just do:
做就是了:
static const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {
#include "TEMPLEVertices.txt"
};
etc.
等等。
And keep just the data in the included files.
并且只保留包含文件中的数据。
You can still declare them as extern
in the compilation unit, but this keeps things a little bit tidier.
您仍然可以将它们声明为extern
在编译单元中,但这会使事情更整洁一些。
回答by 341008
Your header file becomes:
你的头文件变成:
#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_
#define NUM_TEMPLE_OBJECT_VERTEX 10818
extern const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3];
extern const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3];
extern const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3];
#endif
While your source file becomes:
当您的源文件变为:
// include header
const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
// rest of the source
Update: If you are specifying the arrays explicitly, you do not have to mention the sizes. That is you can do:
更新:如果您明确指定数组,则不必提及大小。那就是你可以这样做:
const float TEMPLEVertices[] = {...};
or
或者
const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3];
回答by Mephane
It's very simple, actually; I'll demonstrate with an easier example, a simple primitive constant.
其实很简单;我将用一个更简单的例子来演示,一个简单的原始常量。
In your project, you have two files pi.h
and pi.cpp
.
在您的项目中,您有两个文件pi.h
和pi.cpp
.
The contents of pi.h
looks like this:
内容pi.h
如下:
#ifndef _PI_H
#define _PI_H
extern const double PI;
#endif
The contants of pi.cpp
looks like this:
的内容pi.cpp
如下所示:
#include "pi.h"
const double PI = 3.1415926535;
If you want to use this constant, you just include pi.h
where neccessary. The value will always be read from the same location.
如果你想使用这个常量,你只需要pi.h
在必要的地方包含。该值将始终从同一位置读取。
The same can be done with pretty much anything - arrays, objects, arrays of objects, STL containers etc. Just be sure to not overuse this technique - especially when the objects declared extern
are not const
, you might create some really hard to track side-effects. But for constant data, this is you do it.
几乎任何东西都可以做同样的事情 - 数组、对象、对象数组、STL 容器等。请确保不要过度使用这种技术 - 特别是当声明的对象extern
不是 时const
,您可能会创建一些非常难以跟踪的副作用. 但是对于常量数据,这就是你做的。
回答by Mr.Gate
I usually use a simple trick.
我通常使用一个简单的技巧。
a) In every C/CPP file I define filename_C
b) In every H/HPP file I define filename_H
a) 在每个 C/CPP 文件中我定义文件名_C
b) 在每个 H/HPP 文件中我定义文件名_H
than...
比...
This is going to be your include file
这将是您的包含文件
#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_
#define NUM_TEMPLE_OBJECT_VERTEX 10818
#ifdef _TEMPLE_OBJECT_C
const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...} ; /* Put here your const values */
#else
extern const float TEMPLEVerticies[] ;
#endif
#endif
If I'm not wrong this shoud work (or something very similar to that)... :o)
如果我没有错的话,这应该可以工作(或与此非常相似的东西)... :o)