Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 头文件中的静态常量变量声明_C_Compilation_Header Files - Fatal编程技术网

C 头文件中的静态常量变量声明

C 头文件中的静态常量变量声明,c,compilation,header-files,C,Compilation,Header Files,如果我在头文件中声明static const变量,如下所示: static const int my_variable = 1; 然后将此头包含在多个.c文件中,编译器会为每个文件创建新实例,还是会足够“聪明”地看到它是const,并且只为所有文件创建一个实例 我知道我可以将它设置为外部文件,并在包含此头的.c文件中定义它,但这正是我不想做的。我想它只会为所有文件创建一个实例。但您可以通过在不同的文件中调用它来验证它,并检查它的值,如果您使用该对象的地址,编译器肯定会为每个翻译单元创建一个实例

如果我在头文件中声明static const变量,如下所示:

static const int my_variable = 1;
然后将此头包含在多个
.c
文件中,编译器会为每个文件创建新实例,还是会足够“聪明”地看到它是
const
,并且只为所有文件创建一个实例


我知道我可以将它设置为外部文件,并在包含此头的
.c
文件中定义它,但这正是我不想做的。

我想它只会为所有文件创建一个实例。但您可以通过在不同的文件中调用它来验证它,并检查它的值,如果您使用该对象的地址,编译器肯定会为每个翻译单元创建一个实例。如果您只使用值-它可能足够聪明,完全可以避免创建对象-值将在需要的地方内联。

我详细回答了这个问题。答案是C++,但它对于C也是适用的。 翻译单位是单个源文件。包括标题在内的每个翻译单元将“看到”一个
静态常量int
。在此上下文中,
静态
表示
my_变量
的范围仅限于翻译单元。因此,对于每个翻译单元(“
.c
文件”),您将得到一个单独的
my\u变量


编译器不会“聪明”为所有文件只创建一个实例,这将是错误的,因为您明确告诉它不要这样做(
static
).

一些编译器的猜测和测试并不能说明标准规定的内容。不幸的是,C中的任意类型都没有命名常量。在您的情况下,可以通过枚举来解决<代码>枚举{my_value=1,}这可能会产生您想要的效果,枚举常量在C中的类型为
int
。您将无法获取这样一个野兽的地址。
extern
版本有一个不幸的属性,即您无法使值对其他TUs可见。@JensGustedt:您的意思是编译时可见,与运行时可见相反(一个
extern
变量肯定是可见的)。这是正确的。删除了那个旁注。@DevSolar您知道是否有任何方法可以强制编译器生成一个实例吗?有人告诉我,在GCC中,有一个选项可以让编译器比较常量变量(如我的示例中所示),并将它们合并到一个变量中,但却找不到。@Michał:从你的问题来看,你使用的
my_variable
有点不清楚,为什么只需要一个实例,以及你希望实现什么。这使得在这一点上提出建议有点困难。如果您只需要一个全局变量,就可以使用
extern
,因为这是最干净的方法。如果您需要编译时可见性(例如数组大小),请使用Jens指出的
enum
技巧,或者使用由来已久的
#define MAX_SIZE…
@Michal:使用
extern
而不是
static
?我不明白,由于
static
关键字的原因,对象的地址和值在单元外都是不可访问的,不是吗?@AlterMann是的,范围当然受到
static
的限制,但如果您想打印该变量的地址或进行某种地址算法(当然很奇怪,因为它不是数组)-编译器无法对其进行静默优化和内联,并有义务为其分配存储。啊,好吧,如果您使用该对象的地址让我感到困惑,我想在
&my_variable
中作为变量的地址,你的意思是是否使用了变量?实际上我的意思是是否存在
&my_变量
-如果存在-必须分配存储,因为代码需要有效地址,如果没有-编译器可以直接插入实际值:
foo(my_变量)
实际上与
foo(1)
(因为变量是
const
,并且在整个程序生命周期中具有相同的值),所以没有必要为它分配任何内存。