Error during SWR compile

Posted by Greven on Wed 28 Sep 2005 12:19 AM — 4 posts, 20,605 views.

Canada #0
Ok, this is the system:

Debian Sparc
gcc (GCC) 3.3.5 (Debian 1:3.3.5-13)
Compiling SWRFuss from the fuss web site.

The code:
/*
 * Check hash table for existing occurance of string.
 * If found, increase link count, and return pointer,
 * otherwise add new string to hash table, and return pointer.
 */
char *str_alloc( char *str )
{
   register int len, hash, psize;
   register struct hashstr_data *ptr;

   len = strlen( str );
   psize = sizeof( struct hashstr_data );
   hash = len % STR_HASH_SIZE;
   for( ptr = string_hash[hash]; ptr; ptr = ptr->next )
      if( len == ptr->length && !strcmp( str, ( char * )ptr + psize ) )
      {
         if( ptr->links < 65535 )
            ++ptr->links;
         return ( char * )ptr + psize;
      }
   ptr = ( struct hashstr_data * )malloc( len + psize + 1 );
   ptr->links = 1;
   ptr->length = len;
   if( len )
      strcpy( ( char * )ptr + psize, str );
/*     memcpy( (char *) ptr+psize, str, len+1 ); */
   else
      strcpy( ( char * )ptr + psize, "" );
   ptr->next = string_hash[hash];
   string_hash[hash] = ptr;
   return ( char * )ptr + psize;
}

/*
 * Used to make a quick copy of a string pointer that is known to be already
 * in the hash table.  Function increments the link count and returns the
 * same pointer passed.
 */
char *quick_link( char *str )
{
   register struct hashstr_data *ptr;

   ptr = ( struct hashstr_data * )( str - sizeof( struct hashstr_data ) );/* Line 107 */
   if( ptr->links == 0 )
   {
      fprintf( stderr, "quick_link: bad pointer\n" );
      return NULL;
   }
   if( ptr->links < 65535 )
      ++ptr->links;
   return str;
}

/*
 * Used to remove a link to a string in the hash table.
 * If all existing links are removed, the string is removed from the
 * hash table and disposed of.
 * returns how many links are left, or -1 if an error occurred.
 */
int str_free( char *str )
{
   register int len, hash;
   register struct hashstr_data *ptr, *ptr2, *ptr2_next;

   len = strlen( str );
   hash = len % STR_HASH_SIZE;
   ptr = ( struct hashstr_data * )( str - sizeof( struct hashstr_data ) );/* Line 131 */
   if( ptr->links == 65535 )  /* permanent */
      return ptr->links;
   if( ptr->links == 0 )
   {
      fprintf( stderr, "str_free: bad pointer\n" );
      return -1;
   }
   if( --ptr->links == 0 )
   {
      if( string_hash[hash] == ptr )
      {
         string_hash[hash] = ptr->next;
         free( ptr );
         return 0;
      }
      for( ptr2 = string_hash[hash]; ptr2; ptr2 = ptr2_next )
      {
         ptr2_next = ptr2->next;
         if( ptr2_next == ptr )
         {
            ptr2->next = ptr->next;
            free( ptr );
            return 0;
         }
      }
      fprintf( stderr, "str_free: pointer not found for string: %s\n", str );
      return -1;
   }
   return ptr->links;
}


The warnings:
hashstr.c: In function `quick_link':
hashstr.c:107: warning: cast increases required alignment of target type
hashstr.c: In function `str_free':
hashstr.c:131: warning: cast increases required alignment of target type


I've been trying to get it to compile on this system, and have corrected a few errors so far, but this one has me stumped. I have tried to search this though google, and from what I can understand it is an error that comes from the differnce in pointer sizes from this system compared to most. If anyone has some suggestions, please let me know.
USA #1
what other errors are you getting besides this, also what else have you modified, because that is exactly the same as whats in my hashstr.c file. only difference is I am using gcc-3.2.3.
USA #2
Looks like another one of those 64-bit edge cases. I'm assuming 'Debian Sparc' indicates that you're compiling on a 64-bit CPU? If not then I'm not sure what that warning is trying to say since I've never seen it before.
Australia Forum Administrator #3
I'm not familiar with the error message, or this code, but will take a bit of a guess at it. :)

First, you are passing down a char * pointer, which perhaps can be aligned on a 1-byte boundary.

Then I guess from the code that the pointer is actually to half-way into a string, where the start is actually some hash structure (struct hashstr_data *ptr) which has, amongst other things, a counter of how many times this pointer is used.

Now you have the line (which causes the warning):


ptr = ( struct hashstr_data * )( str - sizeof( struct hashstr_data ) );/



Let us guess that the struct hashstr_data is 6 bytes long. The compiler is complaining that re-casting the pointer might give you an address that is not valid for the new type.

Say, for example, the pointer is at address 1007, and subtracting 6 gives 1001, however the structure itself must be aligned on an 8-byte boundary, hence the subtraction and re-casting has given an invalid address.

Maybe this will never happen, but the compiler is warning that it potentially might, as it doesn't know what the alignment of the incoming char * pointer will be.