Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
![]() | Version 1.9 Build 1367 |
|
We have identified several 64-bit porting problems in the AIPS++ code tree. This list below includes these problems and other potential problems reported by 64-bit porting guides from some of the major vendors.
Compilation on the SGI using CC -64 (64 bit compilation) finds a
handful of problems of type 2 and 3 ( N
10). The most
prevalent problem (N
250) is assuming the equivalence of int
and long usually found with returns from standard library functions.
This section contains examples of the problem categories listed above and recommendations for coding conventions to address each type.
cc-1506 CC: REMARK File = /home/argus/aips++/daily/code/include/aips/Tables/BucketFile.h, Line = 168 There is an implicit conversion from "long" to "unsigned int"; rounding, sign extension, or loss of accuracy may result. { return ::lseek (fd_p, 0, SEEK_END); } lseek returns an off_t not a uInt ^ blockio (opt) cc-1506 CC: REMARK File = /home/argus/aips++/daily/code/aips/implement/FITS/blockio.cc, Line = 117 There is an implicit conversion from "long" to "int"; rounding, sign extension, or loss of accuracy may result. nreadlast = ::read(fd, buffer + iosize, (unsigned)ntoread); ^ read returns an ssize_t not an Int cc-1506 CC: REMARK File = /home/argus/aips++/daily/code/aips/implement/FITS/blockio.cc, Line = 152 There is an implicit conversion from "long" to "int"; rounding, sign extension, or loss of accuracy may result. iosize = ::write(fd,buffer,current); write returns an ssize_t not an Int ^ cc-1506 CC: REMARK File = /home/argus/aips++/daily/code/aips/implement/FITS/fits.cc, Line = 2068 There is an implicit conversion from "unsigned long" to "int"; rounding, sign extension, or loss of accuracy may result. vallen = strlen((char *)val); ^ strlen returns a size_t not an int
The following two lists document the list of library and
system calls that return off_t, size_t (unsigned), and ssize_t (signed).
Library routines that return off_t, size_t or ssize_t:
System calls that return off_t, size_t or ssize_t:
Comments These examples point out a need to check the return types of various standard function calls and not assume they are Int/uInt. These function calls should be embedded in specialized classes where possible. However, a new AIPS++ data type Size is proposed, defined as the largest Int encompassing (off_t, size_t and ssize_t), for use in interfaces which require the specification of file offsets, sizes in bytes or related types. An unsigned counterpart, uSize, will also be added.
/opt/MIPSpro/bin/cc -I.. -I../../include -I../.. -I../../../include -g -64 -DSGI64 -KPIC -c ../../sv.c cc-3187 cc: WARNING File = ../../sv.c, Line = 575 A pointer is converted to a smaller integer. iv = (IV)pv; ^ cc-3187 cc: WARNING File = ../../sv.c, Line = 935 A pointer is converted to a smaller integer. return (IV)SvRV(sv); ^
Comments Inter-conversion of ints and pointer types, or pointer arithmetic using ints is not recommended. However, there are rare cases where it may be necessary, such as the transfer of addresses from C++ to Glish. It is proposed that the new type Size be used in this case to deal with (and flag) these very limited cases. In addition, in C code, (char*)NULL must be used in preference to (char*)0, where required. Some 64-bit compilers will not accept the latter.
cc-1178 CC: WARNING File = ../../ValKern.cc, Line = 68 Argument is incompatible with the corresponding format string conversion. fprintf( stdout, " + %d {ValueKernel}\n", sizeof(ValueKernel) ); ^
Comments %d is for Int, sizeof returns a Long in 64bit and needs %ld. The recommended solution to this problem is to use iostreams.
Comments There are many instances of explicit constants used in AIPS++, in general we get this correctly using only Int constants for Ints, i.e. we don't do
Long a = 0xffff; //Assumes a long is 4 bytes.
Special constants that are sensitive to word length should be defined in OS/Bitmask.h or Constants.h. Some of these can be obtained directly from math limits, and should be used where possible.
Comments We generally do the right thing. Random.cc has some 32/64-bit dependencies of this type. It's important to keep the word length in mind and take care when using the shift operators < < and > > or other bitwise operators, and to use standard C++ bit addressing schemes. Where word lengths of a fixed size are required, such as real-time interfaces or data fillers, {u}Int{8,16,32,64,128} types could be introduced.
Again directly from "SGI MIPSpro 64-bit Porting and Transition Guide".
64-Bit Fortran Porting Guidelines This section describes which sections of your Fortran source code you need to modify to port to a 64-bit system. Standard ANSI Fortran 77 code should have no problems, but the following areas need attention: . Code that uses REAL*16 could get different runtime results due to additional accuracy in the QUAD libraries. . fcom and fef77 are incompatible with regard to real constant folding. . Integer variables which were used to hold addresses need to be changed to INTEGER*8. . C interface issues (Fortran passes by reference). . %LOC returns 64-bit addresses. . %VAL passes 64-bit values. Source code modifications are best done in phases. In the first phase, try to locate all of the variables affected by the size issues mentioned above. In the second phase, locate variables that depend on the variables changed in the first phase. Depending on your code, you may need to iterate on this phase as you track down long sets of dependencies. Examples of Fortran Portability Issues The following examples illustrate the variable size issues outlined above: Example 1: Changing Integer Variables Integer variables used to hold addresses must be changed to INTEGER*8. 32-bit code: integer iptr, asize iptr = malloc(asize) 64-bit code: integer*8 iptr, asize iptr = malloc(asize) Example 2: Enlarging Tables Tables which hold integers used as pointers must be enlarged by a factor of two. 32-bit code: integer tableptr, asize, numptrs numptrs = 100 asize = 100 * 4 tableptr = malloc(asize) 64-bit code: integer numptrs integer*8 tableptr, asize numptrs = 100 asize = 100 * 8 tableptr = malloc(asize)