views:

599

answers:

4

The C source codes that I am trying to port into 64 bit runs without any warning in the 32 bit environment. When I compile in 64 bit linux environment with the compile gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1, it shows the following warning mostly:

warning: cast to pointer from integer of different size

The above warning were the most. I used uintptr_t type and most of those warnings were removed. I could change the type int /unsigned int into 64 bit favorable using uintptr_t. But how can I change the following type to make compatible to 64 bit:

typedef void*  POINTER;

I have changed the following code:

typedef unsigned int    NAT; 

into

typedef uintptr_t NAT

I got following warnings:

warning: passing argument 2 of ‘clause_ComputeSplitFieldAddress’ from   incompatible pointer type
note: expected ‘NAT *’ but argument is of type ‘unsigned int *’
In function ‘clause_DependsOnSplitLevel’:
warning: passing argument 2 of ‘clause_ComputeSplitFieldAddress’ from incompatible pointer type
note: expected ‘NAT *’ but argument is of type ‘unsigned int *’
In function ‘clause_UpdateSplitDataFromNewSplitting’:
warning: passing argument 2 of ‘clause_ComputeSplitFieldAddress’ from   incompatible pointer type
note: expected ‘NAT *’ but argument is of type ‘unsigned int *’

Moreover, after changing type def into uintptr_t which were earlier either int or unsigned int, I am encountering most of the warnings as follows:

warning: inlining failed in call to ‘tptp_StringCopy’: call is unlikely and code size would grow
warning: called from here
warning: inlining failed in call to ‘tptp_StringCopy’: call is unlikely and code size would grow
warning: called from here
warning: inlining failed in call to ‘tptp_StringCopy’: call is unlikely and code size would grow

The fuction tptp_StringCopy is as follows:

static __inline__ char* tptp_StringCopy(void)
{
  char *copy;
  copy = (char*) memory_Malloc(yyleng+1);
  strcpy(copy, yytext);
  return copy;

and the list_Cons is as follows:

static __inline__ LIST list_Cons(POINTER Ptr, const LIST List)
{
  LIST Cell;

  Cell = (LIST)memory_Malloc(sizeof(LIST_NODE));
  Cell->car = Ptr;
  Cell->cdr = List;
  return Cell;
  }

How can I get rid of these warnings?

+1  A: 

I'm not exactly clear on the situation, but it seems that You changed unsigned int to uintptr_t. The former is an unsigned int, the latter is an unsigned int pointer.

In general, that's not a valid substitution to make.

Also, you said the code "runs without warning on 32 bit" but compilation for 64-bit gives you warnings. But it really doesn't matter whether it runs without warning. Maybe you mean, it compiles without warnings. Is that true? The code you've modified, compiles for 32-bit without warning? That would be a surprise.

Cheeso
i have been give a source code. this source codes compiles without warning in 32 bit machine but when i compile those source code into 64 bit machine , i get following warnings in most: cast to pointer from integer of different sizeMy taske is to compile those codes in 64 bit machine without any warnings.For that i made some changes like type int into type uintptr_t. After making those changes i got following warnings at most: warning: inlining failed in call to ‘tptp_StringCopy’: call is unlikely and code size would grow Could you please suggest me the proper approach?
thetna
Cheeso
thetna
There is not a simple answer to your question. In some cases you might want to convert `unsigned int` to `uintptr_t`, and in some cases you will not. No one can answer the original question without having more context - understanding what, exactly, is being contained in the variables that have type NAT. If variables of type NAT store pointers, then using "unsigned int" on a 32-bit machine will *work*, but it is misleading, and based on that, I'd say it's not the right thing to do, and converting to "unsigned int *" gets the right size on 64 bit. But there may be other issues.
Cheeso
`uintptr_t` isn't a pointer type, it's a unsigned integer type large enough such that any object pointer can be converted to and from `uintptr_t` and compare equal to the original pointer.
caf
ok, that's useful. All the prior commentary about why you cannot simply convert from `unsigned int` to `uintptr_t` still apply.
Cheeso
+1  A: 

unsigned int is not interchangeable with uintptr_t on 64-bit systems. int and unsigned int are still 32-bit values on 64-bit machines, but uintptr_t becomes a 64-bit type. The reason that the type is called uintptr_t is because the type is an unsigned integer value that is the same width as a pointer. This means that uintptr_t is 32-bits wide on a 32-bit machine, but it becomes 64-bits wide on a 64-bit machine.

In your code, this means that, with your typedef change, on 64-bit machines NAT* is a 64-bit pointer to a 64-bit variable, but unsigned int* is a 64-bit pointer to a 32-bit variable.

clause_ComputeSplitFieldAddress is still expecting unsigned int* parameters.

Aaron Klotz
Could yo please tell , what will be the interchangeable of :typedef void* POINTER into the 64 bit systems?
thetna
It doesn't change. Pointer types are always 32-bits wide on 32-bit architectures, and they are always 64-bits wide on 64-bit architectures.
Aaron Klotz
There is not a simple answer to your question. In some cases you might want to convert `unsigned int` to `uintptr_t`, and in some cases you will not. No one can answer the original question without having more context - understanding what, exactly, is being contained in the variables that have type NAT.
Cheeso
thank you very much for it. Can you please see once the warning about the inlining? I made changs and now i am getting the majority of warnings about the inlinings like: warning: called from here, warning: inlining failed in call to ‘list_Cons’: call is unlikely and code size would grow.
thetna
There's not enough information there. Can you show the signatures of tptp_StringCopy and list_Cons, and also how you are calling them.
Aaron Klotz
First of all thanks for the reply.i have added the information. i hope that will works and if u need more information then i will be adding.
thetna
You haven't included everything yet -- show us how you are calling those functions. Based on the error message, I am guessing that's where the problem is.
Aaron Klotz
A: 

I suspect the fundamental problem here is that something is assuming that a pointer can be cast to and from a 32-bit integer type without any loss. With 32-bit code this is true, with 64-bit code it is not - pointers are a 64-bit type. This is probably the most common 32-bit to 64-bit porting issue.

What is NAT actually intended to be? If it is an opaque pointer to a structure (dressed up as a 32-bit integer in 32-bit code), you might be best declaring it as a void* rather than a uintptr_t.

Bids
A: 

There's no obvious reason to change the POINTER typedef; a void pointer is still a void pointer in both 32-bit and 64-bit (though the 32-bit version occupies half the space of the 64-bit version). It is only if you abuse POINTER and try to treat it as an integer of some sort that you will run into problems.

You don't show the code for clause_ComputeSplitFieldAddress, but clearly you cannot pass the address of an 'unsigned int' when the function takes a 'NAT *'; you will have to look at where it is called and decide on the appropriate action to fix the calling code - basically, change the relevant unsigned int variables into NAT variables.

For the tptp_StringCopy function, perhaps you should use strdup() - and then you probably won't get an immediate crash if the memory allocation fails.

You don't show the warnings related to List_Cons(), so we can't readily help there.

Generally, you can deal with many of the 32-bit to 64-bit issues by ensuring that you don't do type punning between integers and pointers. When you must, use uintptr_t (and hence <inttypes.h>). And use the print and scan formats defined in <inttypes.h> rigorously when you have variable type definitions for specific typedef names. For example, use

PRIXPTR

to format a uintptr_t value:

printf("0x%08" PRIXPTR "\n", ptr_as_int);

This won't deal with every problem; it will deal with a lot of them.

The compiler is entitled to warn you if wants to about code that is not inlined. There isn't much you can do about that except not request inlining of functions that cannot be inlined.

Jonathan Leffler