Bug: undefined reference to `_countof'

closed account (9EqM4iN6)
The thread I'm coming from:
http://board.byuu.org/viewtopic.php?f=10&t=2421&start=0

This is the program, which I named kodekode.c:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#ifdef _WIN32
#define snprintf _snprintf
#endif

uint32_t read_le32( FILE * source )
{
   unsigned char buffer[ 4 ];
   fread( buffer, 1, 4, source );
   return buffer[ 0 ] + buffer[ 1 ] * 0x100 + buffer[ 2 ] * 0x10000 + buffer[ 3 ] * 0x1000000;
}

int transfer_bytes( FILE * source, FILE * target, size_t count )
{
   unsigned char buffer[ 32768 ];
   while ( count )
   {
      size_t to_read = ( count > 32768 ) ? 32768 : count;
      if ( fread( buffer, 1, to_read, source ) < to_read ) return -1;
      if ( fwrite( buffer, 1, to_read, target ) < to_read ) return -1;
      count -= to_read;
   }
   return 0;
}

int extract_file( const char * filename )
{
   int rval = -1;
   FILE * input_file = NULL, * output_file = NULL;
   uint32_t i, file_count, pointer, size;
   uint32_t * pointers = NULL;
   char output_filename[512];
   input_file = fopen( filename, "rb" );
   if ( !input_file ) { fprintf( stderr, "Error opening file: %s\n", filename ); goto cleanup; }
   file_count = read_le32( input_file );
   pointers = ( uint32_t * ) malloc( ( file_count + 1 ) * sizeof( uint32_t ) );
   if ( !pointers ) { fputs( "Out of memory\n", stderr ); goto cleanup; }
   for ( i = 0; i <= file_count; ++i ) pointers[ i ] = read_le32( input_file );
   for ( i = 0; i < file_count; ++i )
   {
      snprintf( output_filename, _countof( output_filename ) - 1, "%s_file%u.bin", filename, i );
      output_filename[ _countof( output_filename ) - 1 ] = 0;
      output_file = fopen( output_filename, "wb" );
      if ( !output_file ) { fprintf( stderr, "Error opening output file: %s\n", output_filename ); goto cleanup; }
      fseek( input_file, pointers[ i ], SEEK_SET );
      if ( transfer_bytes( input_file, output_file, pointers[ i + 1 ] - pointers[ i ] ) < 0 ) { fputs( "Error writing to output file\n", stderr ); goto cleanup; }
      fclose( output_file );
      output_file = NULL;
   }
   rval = 0;

cleanup:
   if ( output_file != NULL ) fclose( output_file );
   if ( pointers != NULL ) free( pointers );
   if ( input_file != NULL ) fclose( input_file );
   return rval;
}

int main( int argc, const char * const * argv )
{
   int i;
   for ( i = 1; i < argc; ++i )
   {
      fprintf( stderr, "Processing %s...\n", argv[ i ] );
      if ( extract_file( argv[ i ] ) < 0 ) break;
   }
   return 0;
}


This is the terminal input:
gcc kodekode.c -o saga_split

This is the terminal output:
1
2
3
4
/tmp/ccNyeahC.o: In function `extract_file':
kodekode.c:(.text+0x28b): undefined reference to `_countof'
kodekode.c:(.text+0x2c6): undefined reference to `_countof'
collect2: ld returned 1 exit status 


I have GCC 4.5. I run Linux Mint 10, 32-bit, Gnome.

I'm not a programmer, but, since the terminal reported two bugs related to '_countof', and there are two instances of _countof in the program, I figure I can mess around with it until it works, with some guidance.

In which library is _countof defined? You're not linking against it. Given that its a windows thing, you might have trouble.

Instead, stick this at the top:

#define _countof(a) (sizeof(a)/sizeof(*(a)))
Last edited on
You can replace _countof( output_filename ) - 1 with the value 511 directly or:

1
2
3
4
5
   const int filename_bufsize=512;
   char output_filename[filename_bufsize];
[...]
      snprintf( output_filename, filename_bufsize - 1, "%s_file%u.bin", filename, i );
      output_filename[ filename_bufsize - 1 ] = 0;


Edit: a macro works too, of course.
Last edited on
http://msdn.microsoft.com/en-us/library/ms175773(v=vs.80).aspx
I think that you could create it as #define _countof(array) sizeof(array)/sizeof(*array) (I'm no good with macros)
Or just use the value
1
2
3
4
const int size = 512;
char output_filename[size];
//...
output_filename[ size-1 ] = 0;
Although macros are evil...
Since this already only works with arrays anyways, why not define it as a template?
closed account (9EqM4iN6)
@Moschops: Following your directions, I changed the first few lines as such:

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#ifdef _WIN32
#define snprintf _snprintf
#endif

#define _countof(a) (sizeof(a)/sizeof(*(a))) //this being what I added 


And now I have a binary in the directory I cd'ed to. Success! Though I have no idea how to use it.
Last edited on
Topic archived. No new replies allowed.