作为检查,我尝试了以下代码:
const int i = 100;
static int m = 90;
const int p = 40;
int x;
main()
{
const int j = 40;
static int k = 40;
const int n;
char *p = "Rama";
}
因此,请通过gcc编译器告诉哪个变量属于哪个段,因为我得到了以下输出。我写的时候
size ./a.out
我得到了:
text data bss dec hex filename
865 268 12 1145 479 ./a.out
答案 0 :(得分:1)
答案 1 :(得分:1)
通常,未初始化的数据会进入BSS并将数据初始化为DATA(参见here)。
但ISO C并没有强制要求这样做,这完全是一个实施问题。您问题中的dec
和hex
分别是十进制和十六进制中其他三个的总数:
865 + 268 + 12 = 1145 = 0x479
如果你真的想知道,你可以使用各种工具,例如编译时gcc -S
获取汇编语言输出,或nm
及其兄弟查看目标文件。< / p>
答案 2 :(得分:1)
您可以使用nm。这是一个例子: test.c包含您发布的示例:
gcc -o test test.c
nm -p -m test
00001fb0 (__TEXT,__text) non-external (was a private external) dyld_stub_binding_helper
00001fc4 (__TEXT,__text) non-external (was a private external) __dyld_func_lookup
00002010 (__DATA,__data) non-external dyld__mach_header
00002014 (__DATA,__data) non-external _m
00002018 (__DATA,__data) non-external _k.1510
0000200c (__DATA,__data) external _NXArgc
00002008 (__DATA,__data) external _NXArgv
00002000 (__DATA,__data) external ___progname
00001000 (absolute) [referenced dynamically] external __mh_execute_header
00002004 (__DATA,__data) external _environ
00001ff0 (__TEXT,__literal4) external _i
00001fd2 (__TEXT,__text) external _main
00001ff4 (__TEXT,__literal4) external _p
00002038 (__DATA,__common) external _x
00001f70 (__TEXT,__text) external start
(undefined [lazy bound]) external _exit (from libSystem)
您可以使用here描述的技术来控制变量所属的段。 (在MS VC中,您可以使用#pragme data_seg("segname")
)。
答案 3 :(得分:0)
我认为你对static
和const
的含义感到困惑,这是可以理解的,因为你(和我!)一旦你读过这个理论就常常忘记它们的含义。
1)首先,const
。 const
的含义是我们不会通过这个“引用”来改变变量的值。这对于函数参数非常有用,特别是在使用指针时,因此您不需要编辑您不想要的值。例如,任意:
void add(int* result, const int* a, const int* b)
此声明表示如果我们不小心输入a = result + b;
,编译器应该抱怨并拒绝编译。在这种情况下,我们以这样的方式命名变量,即使偶然也不应该覆盖它们,但在更复杂的情况下,它可能会发生。
然而,正如pmg所说,这并不意味着价值不会改变;它只是意味着在谈论该地址/值的这个版本时我们不会改变它。我的观点是,保护您无意改变的参数是有用的,以防您不小心尝试更改它们。如果你想要一个真正固定的值,经常使用预处理器,例如#define TRUE 1
。
2)现在static
。静态意味着“在此编译单元外部不可见”。这就像,我强调,但不等同于类中私有的概念,但在这种情况下,我们讨论的是整个C文件。所以,如果我们在文件helloworld.c
中并且在顶部你写:
static int x = 10;
您无法在x
中使用该版本的helloworld2.c
。
3)虽然我们在这里,但我们也可以做另一个词inline
。 inline
在我看来是一种更好的做宏的方法,意思是“编译器,你应该把它的结果代码放到你调用它的任何地方,而不是花费我们一个函数调用”。无论如何,优化编译器可能会这样做,但这可以作为内联的明确指令。
总之,这些功能都控制语言的各个部分,而不是变量放在可执行文件的各个段中的位置。正如pmg所说,编译器可以做任何喜欢的事情。
如果您想了解编译器的功能,请使用gcc -S
。这为您提供了gcc
的汇编语言输出,它将采用AT&amp; T格式。尝试使用不同的gcc -Ox
x=0,1,2,3
标记,以了解优化的工作原理。
最后,值得注意的是,实际上a.out
只是一个名字;您的现代内核可能在不支持a.out
二进制文件的情况下编译。
我认为这是你真正想问的问题。