当我在main之外声明一些变量时,编译以某种特殊的方式存储它们。
int i=1,j=1;
void main(void)
{
printf("%d\n%d",&i,&j);
}
如果i
和j
都未初始化或等于0或等于某些正值,则它们将存储在内存中的连续地址空间中,而如果i=0
和j = some +ve integer
那么他们的地址相距很远。
问题在于它们存储在连续的地址空间时会导致一些真正的性能问题,例如错误共享(看看here)。我已经了解到,为防止这种情况发生,变量的地址之间应该有一些空格,这些地址会在i=0
和j=any +ve value
时自动提供。
现在,我想要了解的是:
(使用devcpp gcc 4.9.2)
答案 0 :(得分:3)
假设您的意思是SELECT OBJ.OBJ_NAME
FROM OBJ,OBI,OIU,OST,USR
WHERE OBJ.OBJ_KEY=OBI.OBJ_KEY
AND OBI.OBI_KEY=OIU.OBI_KEY
AND OIU.USR_KEY=USR.USR_KEY
AND OIU.OST_KEY=OST.OST_KEY
AND OST.OBJ_KEY=OBJ.OBJ_KEY
AND USR.USR_LOGIN='[Insert User Login here]'
AND OST.OST_STATUS IN ('Enabled','Provisioned');
,请注意以下事项:
printf("%p, %p\n",(void *)&i,(void *)&j);
初始化的全局变量保存在BSS section(这是数据部分的一部分)中以保存二进制大小。其他全局变量保留在data section的其余部分。 (取决于实施细节,不是C规范要求)我如何有意识地执行编译器自动执行的操作?
这是编译器特定的问题,您的编译器文档应该包含对此的答案。
答案 1 :(得分:2)
那里有一个问题,
ID COL1 COL2 D
---------- ----------------------- ----------------------- -
1 ABC DEF DEF ABC Y
2 ABC DEF GHI ABC N
3 ABCD EFGH IJKL MNOP IJKL MNOP ABCD EFGH Y
4 ABCD EFGH IJKL MNOP IJKL QRST EFGH ABCD N
5 ABC ABC DEF DEF ABC DEF N
6 AAA BBB CCC DDD EEE AAA BBB CCC DDD N
7 AAA BBB CCC DDD EEE AAA BBB CCC DDD EEE Y
8 XXX YYYY ZZZ AAA BBB AAA BBB XXX ZZZ YYYY Y
9 A B C D E F G H I J K L L K J I H G F E D C B A Y
10 AA BB CC DD EE AA BB CC DD FF N
10 rows selected.
SQL>
调用undefined behavior。因此,输出无论如何都不合理。您需要使用 printf("%d\n%d",&i,&j);
格式说明符和将相应的参数强制转换为%p
以打印指针。
尽管如此,C标准既没有施加任何约束,也没有提供关于变量在何处以及如何存储在内存中的任何指导。由编译器实现决定如何将不同的变量放在内存中。您需要检查正在使用的编译器的文档,以找出编译器遵循的规则。
以通用方式详细说明,object file由许多细分组成,例如
由编译器决定每个段使用的地址空间(范围/值)。
根据规则,
(void *)
初始化的全局变量(即具有静态存储持续时间)放在0
段中。.bss
段所以,公平地说两个不同段的两个变量的地址不会是连续的。
现在,你的观察结束了。
如果
.data
和i
都未初始化或等于0或等于某些正值,则它们将存储在内存中的连续地址空间
是的,然后所有这些都转到j
或.bss
,编译器通常选择将它们一个接一个地放置。
而如果
.data
和i=0
整数,则他们的地址相隔很远。
这也适用,两个变量现在都放在不同的段中。