tags:

views:

54

answers:

2

I'm using dirname from libgen.h to get the directory path from a filename's path.

This is it's signature:

char * dirname (char *path)

When compiling on a 32 bit machine or using -m32 with gcc, it all works fine.

My code looks like this:

char* path = "/path/to/my/file.txt";
char* path_cpy = strdup(path);
const char* dir = (const char*)dirname(path_cpy);

If I compile on a 64 bit machine, I get the warning:

"warning: cast to pointer from integer of different size"

This will fix the warning, but crashes at runtime:

const char* dir = (const char*)(uintptr_t)dirname(path_cpy);

I have never tried to cross compile for 32/64 bit before, is there a way to fix this?

+5  A: 

Are you including the header file that includes the definition for dirname (that's libgen.h on my system, check in /usr/include)?

The warning "cast to pointer from integer of different size" sounds like it's casting from an int, the default return code from functions with no prototype defined.

It's likely that what's happening is that your int and char * data types are the same size for 32-bit code but, when you switch over to 64 bits, they're actually different sizes.

You could verify this by printing out sizeof(int) and sizeof(char*) and seeing if they're different.

paxdiablo
You are correct, this fixed my issue. I understand why it would break on 64 bit.
Jonathan.Peppers
+1  A: 

You have failed to provide a prototype for dirname (either by including libgen.h or prototyping it yourself), so it implicitly get type int dirname();. Since this does not match the actual function, your program has undefined behavior. (In this case, the upper half of the pointer gets truncated.)

R..