Pergunta

As a check I tried the following code:

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";
}

So please tell which variable goes to which segment as I got the following output over the gcc compiler. When I wrote

size ./a.out

I got:

text   data   bss    dec   hex   filename
865    268     12   1145   479   ./a.out
Foi útil?

Solução

You can use nm. Here is an example: test.c contains the example you posted:

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)

You can use the technique described here to control which segment the variables go to. (In MS VC you can use #pragme data_seg("segname")).

Outras dicas

Variables and stuff go where your compiler wants to put them. You may have some choice on how the compiler behaves through options.

You might like to visit the following links:

http://en.wikipedia.org/wiki/A.out

http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

Normally, uninitialised data would go into BSS and initialised data into DATA (see here).

But ISO C doesn't mandate this sort of thing, it's totally an implementation issue. The dec and hex in your question are the totals of the other three in decimal and hexadecimal respectively:

865 + 268 + 12 = 1145 = 0x479

If you really want to know, there are various tools you can use, such as gcc -S when compiling to get the assembly language output, or nm and its brethren to look inside object files.

I think you're getting confused between the meaning of static and const which is understandable as you (and I!) often forget their meaning once you've read the theory once.

1) Firstly, const. What const means is that we won't change the value of the variable through this "reference" to it. This is really useful for function arguments, particularly when using pointers, so that you don't edit values you didn't intend to. For example, arbitrarily:

void add(int* result, const int* a, const int* b)

This declaration means if we accidentally typed a = result + b; the compiler should complain and refuse to compile. In this case we've named the variables in such a way that we shouldn't overwrite them even by accident but in more complicated scenarios, it can happen.

As pmg says, however, this does not mean the value will not change; it simply means when talking about this version of that address/value we will not change it. My point here is that it is useful to protect arguments you don't intent to change in case you accidentally do try to change them. If you want a truly fixed value preprocessor is often used, e.g. #define TRUE 1.

2) Now static. Static means "not visible outside this compilation unit". This is like, and I stress like, but not equivalent to, the notion of private in classes, but in this case we're talking about the entire C file. So, if we are in file helloworld.c and at the top you write:

static int x = 10;

You cannot then use that version of x in helloworld2.c.

3) Whilst we are at it, we might as well do the other word inline. inline is sort-of a nicer way to do macros in my opinion and means "compiler, you should really put the resultant code of this into wherever you call it, rather than costing us a function call". Optimising compilers might do this anyway but this acts as an explicit instruction to inline where possible.

In summary, these features all control parts of the language and not where the variable gets placed in the executable's various segments. As pmg says, the compiler can do whatever it likes.

If you want an idea of what the compiler has done, use gcc -S. This gives you the assembly language output from gcc which will be in AT&T format. Try this with different gcc -Ox where x=0,1,2,3 flags to get an idea of how optimisation works.

Finally, it is worth noting that in fact a.out is merely a name; your modern kernel is probably compiled without support for a.out binaries.

I think that's the question you were really trying to ask.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top