Pointer arithmatic failed to compile, gcc says invalid type conversion

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?

Answers


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.


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)


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);

Need Your Help

Error querying "Microsoft.ACE.OLEDB.12.0" provider from SQL Server

sql-server tsql

This is not a question, but this post may be useful for community because I could not find the answer on the Internet.