Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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_Db2 - Fatal编程技术网

C 变量的顺序是否由标准定义?

C 变量的顺序是否由标准定义?,c,db2,C,Db2,见下文: static char start_marker; static int var_1; static int var_2; /* ... */ static int var_n; static char end_marker; 我想初始化部分中的所有变量。以下代码有效吗 memset(&start_marker, 0, &end_marker-&start_marker); 请注意,我不能在这里使用结构,因为db2预处理器将这些字段用作所谓的主机变量。不,它

见下文:

static char start_marker;
static int var_1;
static int var_2;
/* ... */
static int var_n;
static char end_marker;
我想初始化部分中的所有变量。以下代码有效吗

memset(&start_marker, 0, &end_marker-&start_marker);

请注意,我不能在这里使用结构,因为db2预处理器将这些字段用作所谓的主机变量。

不,它无效。编译器可以随心所欲地布局全局变量和静态变量。

您的代码不仅依赖于顺序,还依赖于连续性:我在这里没有任何保证


但是,您应该考虑将所有这些变量分组在<代码>结构> <代码> .< /p>

不,您不能保证它们以特定的方式排序,也不能保证它们在内存中毗连。

如果要对其进行初始化,请使用:

void initVars() {
    start_marker = 0;
    var_1 = 0;
    var_2 = 0;
    /* ... */
    var_n = 0;
    end_marker = 0;
}

不要这样做,通常这是无用的,而且容易出错。具有静态分配的变量从一开始就初始化为
0
。不需要初始化它们。此外,编译器选择正确的
0
来执行此操作,例如
0.0
用于双精度或空指针常量用于指针等

如果你想让你和代码的读者明白,你可以给它一个显式的初始值设定项,例如

static int var_1 = { 0 };
此回退初始值设定项应始终有效。更好的是,如果您有与C99兼容的编译器,则有指定的初始值设定项:

static int arr[3] = { [0] = 0, [1] = 42,  };
初始值设定项中未提及的字段默认情况下再次初始化为
0
,例如元素
arr[2]

所有这些显式初始化都适用于静态分配变量或堆栈变量(
auto
)。
memset
经常用于此目的。让编译器帮你做就行了。在最坏的情况下,他只会做一个
memset
,但通常他有一个更聪明的方法来做。

首先-通过C标准静态变量被预初始化为零-几乎是一个常见问题

如果您只需要零初始化静态,那么无需执行任何操作

如果您希望在稍后某个时间点一次性将整批静态变量归零,和/或要求将所述批预初始化为特定的其他值,则必须指示链接器(而不是编译器)将这些变量放入特定的已知地址。这称为“区段”,这些区段的去向可以由链接器脚本控制。
请参见此处的示例:

这说明了默认初始化代码是如何工作的

你甚至可以让链接器创建/填充一个带有地址的符号(指针),如果你的特殊部分。在您的C/C++代码中,您需要执行
externvoid*varblkaddr;extern size\u t varblksize
,并实际让链接器脚本为您创建具有这些名称的变量,初始化为您选择的地址

事实上,stackoverflow是一个很好的资源。这将有助于:


正如其他人所说,静态存储持续时间的变量总是初始化的。如果不提供显式初始值设定项,它们将被初始化为零

如果希望以后能够使用
memset
将它们作为一个组全部重置为零,则需要将它们全部放入
结构中。否则,它们的位置是独立的


请记住,从标准的角度来看,
memset
归零并不要求与归零初始化相同。允许空指针和浮点零值具有除所有零位以外的表示形式。实际上,这是标准赋予实现的一种愚蠢的自由,在现代世界中,你永远不会遇到这种实现,因此我会忽略(非)问题。

我主要依赖于开始标记结束标记的顺序,这似乎是一个错误的假设,因为答案表明谢谢,但问题是我想在使用它们之后重新初始化它们,以便下次可以重用它们。如果旧值出现在变量shm中,使用
static
变量,然后首先嗅到设计缺陷,这对我的应用程序来说是致命的。如果你真的需要它们,如果你有C99,即使是重新初始化,也有类似的方法使用“复合文字”。但是计算文字也需要结构。@codymanix:当然。但是正如我所说的,如果你使用
静态
变量作为不同功能之间的简单通信方式,那么你的设计很可能是有缺陷的。为保存状态的应用程序定义一个
状态
结构,并在函数中准确地分离出初始化该状态所需的内容。那么,这样一个状态变量是否是静态的、自动的或者malloced应该很重要。这就是我目前正在做的事情,但是它比较慢(好的,没有那么多),而且有可能我忘记了一个变量。是的,这取决于你想让你的程序多独立于平台,我不认为这是一个平台问题。有些东西(比如位被分配给位字段的顺序)是由实现定义和记录的,要么是因为C标准要求对它们进行记录,要么是因为无法确保库的ABI兼容性。其他事情,如自变量的相对位置,是程序永远不应该注意的,它们可能会随着编译器的不同版本、优化级别、库的存在等而改变。取决于它们的不是平台dep,而是被破坏。。。