Thread: How to make code portable when function names differ between platforms?

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    101

    How to make code portable when function names differ between platforms?

    I am trying to write code that is portable across Windows and Mac OS X. The problem I have is that I need to read and write large files over 4GB, so I need to use 64 bit versions of fseek() and ftell(). On Windows (using MinGW), I can use fseeko64() and ftello64(). However, these functions do not exist on Mac OS X. It uses ftell(), and I believe supports 64 bit files by default if using 64 bit variables to store file offsets (I am using int64_t).

    Another problem is that MinGW doesn't like the %lld printf specifier. It wants %I64d instead. Is there a way I can change these based on a preprocessor statement? Something like this:

    Code:
    #if defined(_WIN32)
    #define %lld %I64d
    #endif
    That doesn't work, but you see what I'm getting at.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    Quote Originally Posted by synthetix View Post
    I am trying to write code that is portable across Windows and Mac OS X. The problem I have is that I need to read and write large files over 4GB, so I need to use 64 bit versions of fseek() and ftell(). On Windows (using MinGW), I can use fseeko64() and ftello64(). However, these functions do not exist on Mac OS X. It uses ftell(), and I believe supports 64 bit files by default if using 64 bit variables to store file offsets (I am using int64_t).

    Another problem is that MinGW doesn't like the %lld printf specifier. It wants %I64d instead. Is there a way I can change these based on a preprocessor statement? Something like this:

    Code:
    #if defined(_WIN32)
    #define %lld %I64d
    #endif
    That doesn't work, but you see what I'm getting at.
    Also don't forget that there are probably endianness issues propping up when working with Mac vs. PC.
    iMalc: Your compiler doesn't accept misspellings and bad syntax, so why should we?
    justin777: I have no idea what you are talking about sorry, I use a laptop and there is no ascii eject or something

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The usual trick is something like
    Code:
    #if defined (_WIN32)
    #define LONGLONGSPEC %I64d
    #else
    #define LONGLONGSPEC %lld
    #endif
    I think your endianness issues are probably ok, unless you are on a non-Intel Mac, but it may not hurt to check if you're writing data files that need to cross platforms.

  4. #4
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Quote Originally Posted by tabstop View Post
    The usual trick is something like
    Code:
    #if defined (_WIN32)
    #define LONGLONGSPEC %I64d
    #else
    #define LONGLONGSPEC %lld
    #endif
    Thanks. That worked but I had to use quotes around the specifiers like this:
    Code:
    #if defined(_WIN32)
    #define LONGLONGSPEC "%I64d"
    #else
    #define LONGLONGSPEC "%lld"
    #endif
    And then I called the printf like this:
    Code:
    printf("Here's a big ol' number: "LONGLONGSPEC"\n", (int64_t)bignum);
    I think your endianness issues are probably ok, unless you are on a non-Intel Mac, but it may not hurt to check if you're writing data files that need to cross platforms.
    The biggest problem I've run into with this is with legacy file formats that want things in big-endian format. QuickTime files are notorious for this, so I have to do endian swaps a lot to make the data valid.

  5. #5
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Any idea how to swap out function names based on whether the environment is Windows or Mac? I need ftello64() on Windows, and just ftell() on Mac.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    #include <stdio.h>
    #include <math.h>
    
    #ifdef MAKEITCOS
    #define TRIGFUNC cos
    #else
    #define TRIGFUNC sin
    #endif
    
    int main(void) {
        double result;
        result = TRIGFUNC (0.0);
        printf("%g\n", result);
        return 0;
    }
    You don't have to worry about reaching into quoted string literals this time, like you did last time.

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Quote Originally Posted by tabstop View Post
    Code:
    #include <stdio.h>
    #include <math.h>
    
    #ifdef MAKEITCOS
    #define TRIGFUNC cos
    #else
    #define TRIGFUNC sin
    #endif
    
    int main(void) {
        double result;
        result = TRIGFUNC (0.0);
        printf("%g\n", result);
        return 0;
    }
    You don't have to worry about reaching into quoted string literals this time, like you did last time.
    Works great! Thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 10-07-2009, 08:19 AM
  2. Replies: 16
    Last Post: 05-14-2009, 02:48 PM
  3. Evaluating differ. parts of a single #.
    By alexpos in forum C Programming
    Replies: 2
    Last Post: 10-19-2005, 08:36 PM
  4. Is fork function portable over different hardware
    By gandalf_bar in forum Linux Programming
    Replies: 1
    Last Post: 06-09-2004, 06:34 AM
  5. Replies: 6
    Last Post: 01-03-2003, 05:40 PM