CC address calculation not as exspected

From: <kum_at_runpmx.rutgers.edu>
Date: Wed, 13 Sep 95 10:14:22 -0400

Hi,

Processing 'sequentially' stored data, like tape records, I usually
do a read of the data block into a char buffer and extracted the
imformation applying structures (usually several different structures).
The 'adventage' is to use readable names for the structured data words.

I used to do this routinely and wonder, because
I noticed the following problem.
Depending on the order of data types in a structure declaration
the calculated address returned by the compiler varies.

I tried pointer type casting and a union declaration, I tested the code on
ULTRIX and Digital Unix using cc and gcc.
The result is the same. So, I blamed it on my code.
But after spending some time playing around and reducing the code to a
simple example, I cannot 'see' whats wrong.

May be someone out has an idea or knows it's not supposed to work.
Here is the code example.


#include <stdio.h>

typedef struct tape_header
    {
    unsigned short int RecordType; /* tape header type= 1 */
    unsigned short int RecordLength; /* number of bytes in this record */
    unsigned short int RecordVer; /* record version or subtype */
    unsigned int ByteOrder; /* to determine byte ordering */
    char exp_title1[40]; /* first part of exp title */
    char exp_title2[40]; /* 2nd part of exp title */
    char time[9]; /* hh:mm:ss */
    char date[9]; /* yy/mm/dd */
    unsigned short int TapeNum; /* tape number in this experiment */
    unsigned short int TapeUnit; /* specifies which unit wrote this tape
*/
} TAPE_HEADER;

TAPE_HEADER *tape_hp; /* pointer to structure */

char tbuf[1024]; /* data buffer */

int nb; /* number of bytes */
int fd, mtfd;

main (argc,argv)
int argc;
char ** argv;
{

    char erstr[80], infile[64];
    
    if(argc > 1) { /* other than default */
        strcpy(infile,argv[1]);
        if((mtfd = open(infile,0)) < 0) {
            sprintf(erstr,"cannot open %s", infile);
            perror (erstr);
            exit(0);
        }
    }
    else {
        printf("filename missing\n");
        exit(1);
    }
    findhead();
}

int findhead () { /* find header block */

    if((nb = read (mtfd, tbuf, 112)) < 0) {
        perror(" ");
        return(-1);
    }

    tape_hp = (TAPE_HEADER *)tbuf; /* equating the pointers */

    printf("tbuf = %u thp = %u\n",tbuf,tape_hp);

    printf("%u\n",&tape_hp->RecordType);
    printf("%u\n",&tape_hp->RecordLength);
    printf("%u\n",&tape_hp->RecordVer);
    printf("%u\n",&tape_hp->ByteOrder);
    printf("%u %s\n",tape_hp->exp_title1,tape_hp->exp_title1);
    printf("%u %s\n",tape_hp->exp_title2,tape_hp->exp_title2);
    printf("%s\n",tape_hp->time);
    printf("%s\n",tape_hp->date);
    return(0);
}

/*********

Running this code on a data set returns the following:
tbuf = 1073742560 thp = 1073742560
1073742560
1073742562
1073742564
1073742568 !!!!!!!! this address should be 1073742566!!!!!!!
1073742572 8Po SD
1073742612 tgers et al.
:40:18
/10/95
                  after the shift in the address the rest is shifted too.
If the tape_header structure is modified so that ByteOrder is also
u_short and a unsigned short int dummy is used to pad the structure
like
typedef struct tape_header
    {
    unsigned short int RecordType; /* tape header type= 1 */
    unsigned short int RecordLength; /* number of bytes in this record */
    unsigned short int RecordVer; /* record version or subtype */
    unsigned short int ByteOrder; /* to determine byte ordering */
    unsigned short int dummy;
    char exp_title1[40]; /* first part of exp title */
    char exp_title2[40]; /* 2nd part of exp title */
    char time[9]; /* hh:mm:ss */
    char date[9]; /* yy/mm/dd */
    unsigned short int TapeNum; /* tape number in this experiment */
    unsigned short int TapeUnit; /* specifies which unit wrote this tape
*/
} TAPE_HEADER;

the ouput returnes:
tbuf = 1073742560 thp = 1073742560
1073742560
1073742562
1073742564
1073742566 dummy address not written out!
1073742570 198Po SD
1073742610 Rutgers et al.
02:40:18
06/10/95
as exspected.

At this point the input data do not matter, any file can be used to run
the test.
Using instead of the type casting of the pointers a union declaration
for tbuf and TAPE_HAEDER makes no difference. The result depends on the
order of short and int in the structure declaration.

short int short int short int
short short int int short short
short int int short short short
int short short
                                 short
bad bad bad ok ok ok

I appreciate your comments although I realize this is not the typical
question for system administrators. But if something does not work ...
it is always the responsibility of the system administrator.

Gerfried Kumbartzki
Rutgers University
Physics Department
Received on Wed Sep 13 1995 - 16:55:05 NZST

This archive was generated by hypermail 2.4.0 : Wed Nov 08 2023 - 11:53:45 NZDT