×

Loading...
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。

64位AIX上的问题:unsigned long 转换为int会出错,同样的问题在Solaris(64位),AIX(32位),Redhat,HP UX(64bit)都不会出现. 是否要打什么补丁才行?

Here is a test program:

#include <stdio.h>
void test(int *tmp);
main()
{
unsigned long i=789;
printf("before test(), i = %ld\n", i);
test((int *)&i);
printf("after test(), i = %ld\n", i);
}
void test(int *tmp)
{
printf("in test(), *tmp=%d\n", *tmp);
*tmp = 123;
printf("in test(), *tmp=%d\n", *tmp);
}

The test program runs on AIX(32bit), Solaris, Linux, HP UX and I get the same correct output like below:

#gcc test.c -o tst
# ./tst
before test(), i = 789
in test(), *tmp=789
in test(), *tmp=123
after test(), i = 123
#

But for AIX (64bit), I get:

# gcc -maix64 test.c -o tst
# ./tst
before test(), i = 789
in test(), *tmp=0
in test(), *tmp=123
after test(), i = 528280978197
#

I know this is concerned with the data alignment for 64bit system. In my opinion there must be some patches or methods to fix it, but I am still not sure what it is.

Any suggestion will be appreciated.
Report

Replies, comments and Discussions:

  • 工作学习 / 专业技术讨论 / 64位AIX上的问题:unsigned long 转换为int会出错,同样的问题在Solaris(64位),AIX(32位),Redhat,HP UX(64bit)都不会出现. 是否要打什么补丁才行?
    Here is a test program:

    #include <stdio.h>
    void test(int *tmp);
    main()
    {
    unsigned long i=789;
    printf("before test(), i = %ld\n", i);
    test((int *)&i);
    printf("after test(), i = %ld\n", i);
    }
    void test(int *tmp)
    {
    printf("in test(), *tmp=%d\n", *tmp);
    *tmp = 123;
    printf("in test(), *tmp=%d\n", *tmp);
    }

    The test program runs on AIX(32bit), Solaris, Linux, HP UX and I get the same correct output like below:

    #gcc test.c -o tst
    # ./tst
    before test(), i = 789
    in test(), *tmp=789
    in test(), *tmp=123
    after test(), i = 123
    #

    But for AIX (64bit), I get:

    # gcc -maix64 test.c -o tst
    # ./tst
    before test(), i = 789
    in test(), *tmp=0
    in test(), *tmp=123
    after test(), i = 528280978197
    #

    I know this is concerned with the data alignment for 64bit system. In my opinion there must be some patches or methods to fix it, but I am still not sure what it is.

    Any suggestion will be appreciated.
    • 你根本就不应该这么转换。没用过aix ,不过这明显是long和int字长不一样造成的。
      789 ==0x03 15, 123 == 0x7B
      528280978197==0x7B 00 00 03 15

      说明aix 上int 是4字节,long是8字节,字节序是高位在前。
      • 必需这么转换,同样的问题还会出现在long和short,short和int,int和char之间的转换,程序里这样的语句成千上万,我没法一一去改和测试.高低字节你分析的很对,高手.
        • 既然你的程序在 Redhat(pc? ) 上能跑,那4字节 的long似乎已经够用了。你可以把所有的long换成LONG什么的,再来个define LONG int?
          • 目前这也是我的解决方案之一
            • 选中的方案是:改系统内核为32bit模式,重新编译所有应用.
    • test((int *)&i); <-- 这步错了.
    • come on, man.我要的是解决方案,不是要讨论这些初级的编程问题.
      • 在主程序里按操作系统宏定义i的类型.
    • 原来我们在HP和PC之间通信的时候遇到过类似的问题
      用的是下面的文章提到的函数,不过那时候没有64位的。

      http://www.awprofessional.com/articles/article.asp?p=169505&seqNum=4&rl=1
      • 跨主机通信字节序列处理有标准的封装函数,省心多了.
    • 97年左右我们移植系统的时候遇到过类似的高低位问题,最终的解决方案是用awk写程序把所有的C程序改了
      • 就怕最后只有这一条路,所以才来这里求助啊
    • 请问您的编译选项里面有没有64位的那个东东?4年前的印象了。。。久不写C了
      • 有-maix64, 环境变量中有OBJECT_MODE=64.
    • 给你一个小小的提示:
      你以后再这里多回答一些问题,估计你这个问题就有人帮你了.
      • Good idea! Thanks
    • 你把这八个字节看成字符串,然后把它转成任何数字都可以了,就是简单的移位.
      老是看见你在这里问方案,却很少干任何其它事情,下次要请我喝茶.
      • 我估计你的问题的答案是这样的,没有时间读你的那些乱七八糟的代码.
        • 哈哈,没问题.你在温哥华就可以请你.不是我不回答问题,水平不够啊.
          • 那好.如果不行,研究一下#prama pack(1) most compiler support it.