views:

133

answers:

4

For this code:

#include<stdio.h>

void hello() { printf("hello\n"); }
void bye()   { printf("bye\n");   }

int main() {
    printf("%p\n", hello); 
    printf("%p\n", bye);
    return 0;
}

output on my machine:

0x80483f4
0x8048408

[second address is bigger in value]

on Codepad

0x8048541
0x8048511

[second address is smaller in value]

Does this have anything to do with endian-ness of the machines? If not,

  • Why the difference in the ordering of the addresses?

  • Also, Why the difference in the difference?

    0x8048541 - 0x8048511 = 0x30

    0x8048408 - 0x80483f4 = 0x14


Btw, I just checked. This code (taken from here) says that both the machines are Little-Endian

#include<stdio.h>
int main() {    
    int num = 1; 
    if(*(char *)&num == 1)
        printf("Little-Endian\n");
    else    
        printf("Big-Endian\n");
    return 0;       
}
+3  A: 

The location and ordering of functions is extremely specific to platform, architecture, compiler, compiler version and even compiler flags (especially those).

Marcelo Cantos
+5  A: 

It has nothing to do with endinanness, but with the C++ standard. C++ isn't required to write functions in the order you see them to disk (and think about cross-file linking and even linking other libraries, that's just not feasable), it can write them in any order it wishes.

About the difference between the actual values, one compiler might add guards around a block to prevent memory overrides (or other related stuff, usually only in debug mode). And there's nothing preventing the compiler from writing other functions between your 2 functions. Keep in mind even a simple hello world application comes with thousands of bytes of executable code.

The bottom line is: never assume anything about how things are positioned in memory. Your assumptions will almost always be wrong. And why even assume? There's nothing to be gained over writing normal, safe, structured code anyway.

Blindy
@Blindy: thanks for the answer! what you have said answers my question. But just wondering, there would be *some way* telling the compiler how to place objects in memory. **Is there some text on this memory management part of compilers that I can go through to understand this better?**
Lazer
Mmmm not really, you only really tell the compiler a semi-high level view of what you mean (ie C code). The compiler handles translating it down to code segments. This being said, specific compilers have (different) ways of letting you express how you want structures to be packed (the space between fields) and aligned (the distance from 4/8/16/32/64 bit boundaries). You can't tell the compiler anything about the actual code being compiled though.
Blindy
+6  A: 

No, this has nothing to do with endianness. It has everything to do with compilers and linkers being free to order function definitions in memory pretty much as they see fit, and different compilers choosing different memory layout strategies.

Owen S.
+1  A: 

You are printing function addresses. That's purely in the domain of the linker, the compiler doesn't do anything that's involved with creating the binary image of the program. Other than generating the blobs of machine code for each function. The linker arranges those blobs in the final image. Some linkers have command line options that affect the order, it otherwise rarely matters.

Endian-ness cannot affect the output of printf() here. It knows how to interpret the bytes correctly if the pointer value was generated on the same machine.

Hans Passant