0

I wish to calculate the distance between a program's bss section and the start of heap section, so I've got a program like this:

$ cat 1.cpp

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
int empty;//bss
int main()
{
  char*p=(char*)malloc(0);
  printf("%d\n",(int)p-(int)&empty);
  return 0;
}

When I compile that code using:

$ g++ 1.cpp

The errors are:

1.cpp: In function ‘int main()’:
1.cpp:8:22: error: cast from ‘char*’ to ‘int’ loses precision [-fpermissive]
   printf("%d\n",(int)p-(int)&empty);
                  ^
1.cpp:8:30: error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive]
   printf("%d\n",(int)p-(int)&empty);
                          ^

I don't think it's improper to convert an int* to int. I found plenty of examples doing this on the internet.

Why is my code not compiling?

2501
  • 25,460
  • 4
  • 47
  • 87
Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • @user1810087 Your removal of the C++ tag was incorrect. OP is using g++ and the code is C++ (it will also compile in C since the languages are similar, but the question is not about C). – 2501 Sep 21 '16 at 10:29

3 Answers3

3

Don't always trust what you read on the Internet.

Presumably, you're on a platform where pointers are 64-bit and int is 32-bit. In this case, a conversion from a pointer to int loses precision, and you're compiling with the right flags to make this an error. Well done!

The type you're looking for to convert a pointer to an integral type is uintptr_t. This is defined by the standard to be of sufficient width to allow for lossless conversion.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • Also, the assumption that malloced areas should be in any relation to .bss is generally wrong nowadays. There may be gaps, and there are implementations that allocate from mmaped areas way above bss. – arsv Sep 21 '16 at 10:16
1

The type to cast to from pointers should be uintptr_t, which is guaranteed not to lose precision, see also fixed width integer types.

If you insist on using printf, then you need to find the right formatter, because that is not fixed. Otherwise, use:

std::cout << reinterpret_cast<uintptr_t>(p);
2501
  • 25,460
  • 4
  • 47
  • 87
stefaanv
  • 14,072
  • 2
  • 31
  • 53
1

You may want p-reinterpret_cast<char*>(&empty)

But I don't see any reason to calculate distance between the two address. (and is undefined behavior as noted by @mch)

2501
  • 25,460
  • 4
  • 47
  • 87
apple apple
  • 10,292
  • 2
  • 16
  • 36
  • `%d` is the wrong specifier to print the difference between 2 pointer. It is also undefined behaviour to calculate the difference between 2 pointer which do not point to the same memory block. – mch Sep 21 '16 at 09:22
  • well, I use `%d` because the OP use it, and I state that I don't see any reason to do so – apple apple Sep 21 '16 at 09:26
  • The question is tagged with C not C++. The answer must follow the same tag. – 2501 Sep 21 '16 at 09:56
  • @2501 The question was originally tagged C++, and the OP uses `g++` to compile a file named `1.cpp`. I am highly skeptical of the change in tag to C... – Barry Sep 21 '16 at 10:12
  • @Barry You are correct, I was mislead by the incorrect edit, and I didn't read the question. I have changed the tag to C++. – 2501 Sep 21 '16 at 10:26