// ****************************************************************** // // bugreport.c // // This short little program demonstrates what I believe to be a bug // in the otherwise-amazing GMP library. // // Details: // 1. mpz_out_raw() is used to dump 4 values to a file. // // 2. When the program is run again, we attempt to read // in the previously saved values using mpz_inp_raw(). // The 4 saved values are loaded correctly, but an extra // unexpected value is also loaded. // // Command Used to Compile: // gcc -lgmp -o bugreport bugreport.c // // Usage instructions: // 1. Compile using the above line. // 2. Run the program once. // 3. Run the program again and note extra loaded value. // // Tested on the following configurations: // // 1. AMD Athlon (Classic, the old Slot-A beasts), // default Linux Mandrake 8.2 install // `gcc -v` yields: // // Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/specs // gcc version 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk) // // GMP installed from RPM: `rpm -qi libgmp3 | grep -i version` yields: // Version : 3.1.1 // // 2. Intel Celeron (Laptop), default Linux Mandrake 8.2 install // 'gcc -v' is the same as above // // GMP version 4.1 was compiled/installed from source // // // Keep up the great work! // Peter Kristolaitis // address@hidden // // ****************************************************************** #include #include int main() { FILE *fd; // try to open the file in read mode to see if it exists... fd = fopen("numbers.lst", "r"); if ( fd == NULL ) { // file DOESN'T exist... open the file for writing and // dump some values to it printf("File doesn\'t exist... creating it!\n"); fd = fopen("numbers.lst", "w"); if ( fd != NULL ) { // file opened for writing... dump 4 values to it // ( use the first four prime numbers, just for fun ) mpz_t bigNum; printf("Saving value of 2...\n"); mpz_init ( bigNum ); mpz_add_ui ( bigNum, bigNum, 2 ); mpz_out_raw ( fd, bigNum ); mpz_clear ( bigNum ); printf("Saving value of 3...\n"); mpz_init ( bigNum ); mpz_add_ui ( bigNum, bigNum, 3 ); mpz_out_raw ( fd, bigNum ); mpz_clear ( bigNum ); printf("Saving value of 5...\n"); mpz_init ( bigNum ); mpz_add_ui ( bigNum, bigNum, 5 ); mpz_out_raw ( fd, bigNum ); mpz_clear ( bigNum ); printf("Saving value of 7...\n"); mpz_init ( bigNum ); mpz_add_ui ( bigNum, bigNum, 7 ); mpz_out_raw ( fd, bigNum ); mpz_clear ( bigNum ); printf("Closing file...\n"); fclose(fd); printf("All done!\n"); printf("Saved 4 values to file.\n"); printf("Run this program again to see the bug!\n"); } else { printf("Couldn\'t open file for writing!\n"); return 1; } } else { // file already exists... load values from file... // Note that file is already open for reading! mpz_t bigNum; unsigned count = 0; printf("File already exists... loading values from file.\n"); mpz_init ( bigNum ); while ( !feof(fd) ) { mpz_inp_raw ( bigNum, fd ); printf("Loaded value "); mpz_out_str ( stdout, 10, bigNum ); printf(" from file.\n"); count++; } printf("Loaded %d values from file.\n", count); fclose(fd); } return 0; }