This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Strange Behavior
- From: "Eric Lemings" <lemings at roguewave dot com>
- To: <gcc at gcc dot gnu dot org>
- Date: Thu, 8 Mar 2007 10:06:57 -0700
- Subject: Strange Behavior
Greetings,
While writing a generic C++ algoririthm for base64 encoding, I came
across
some very strange behavior. If you take the following program
(admittedly
verbose for debugging purposes) and test it on some data, say the logo
image
from www.google.com, you may notice (depending on your platform) that
the
byte at offset 0230 (octal) is either read in with an incorrect value or
is
skipped entirely.
template < class InputItor, class OutputItor >
OutputItor
encode (InputItor first, InputItor last,
OutputItor out) {
static const char s [] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
while (first != last) {
unsigned char uc0 = *first++;
int i0 = (uc0>>2) & 0x3f;
char c0 = s [i0];
*out++ = c0;
unsigned char uc1 = (first == last? 0: *first++);
int i1 = ((uc0<<4) + (uc1>>4)) & 0x3f;
char c1 = s [i1];
*out++ = c1;
bool eof = (first == last);
unsigned char uc2 = (eof? 0: *first++);
int i2 = ((uc1<<2) + (uc2>>6)) & 0x3f;
char c2 = (eof? '=': s [i2]);
*out++ = c2;
int i3 = uc2 & 0x3f;
char c3 = (first == last? '=': s [i3]);
*out++ = c3;
}
return out;
}
#include <algorithm>
#include <fstream>
#include <iterator>
#include <iostream>
#include <string>
using namespace std;
extern int
main () {
ifstream in ("logo.gif", ios_base::binary);
istream_iterator< char > first (in);
istream_iterator< char > last;
string s;
encode (first, last, back_inserter (s));
cout << s;
return 0;
}
You can boil the while loop down to it's basic read operations and still
see the same results.
while (first != last) {
unsigned char uc0 = *first++;
unsigned char uc1 = (first == last? 0: *first++);
unsigned char uc2 = (first == last? 0: *first++);
}
Just for sake of sanity, I wrote a quick version of the algorithm in C.
Naturally, this program behaves as it should.
#include <stdio.h>
#include <stdlib.h>
extern int
main (int argc, char* argv []) {
FILE* in = fopen ("logo.gif", "rb");
if (in == NULL) {
perror (argv[0]);
exit (EXIT_FAILURE);
}
const char s [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
while (!feof (in)) {
unsigned char uc0 = fgetc (in);
int i0 = (uc0>>2) & 0x3f;
char c0 = s [i0];
putc (c0, stdout);
unsigned char uc1 = (feof (in)? 0: fgetc (in));
int i1 = ((uc0<<4) + (uc1>>4)) & 0x3f;
char c1 = s [i1];
putc (c1, stdout);
int eof = feof (in);
unsigned char uc2 = (eof? 0: fgetc (in));
int i2 = ((uc1<<2) + (uc2>>6)) & 0x3f;
char c2 = (eof? '=': s [i2]);
putc (c2, stdout);
int i3 = uc2 & 0x3f;
char c3 = (feof (in)? '=': s [i3]);
putc (c3, stdout);
}
fclose (in);
return 0;
}
If anyone can shed some light on the strange behavior in the C++
program,
I would appreciate it very much.
Thanks,
Eric.