D
DSF
Hello!
I have some code that compiles with no errors/warnings that would
seem to me to have an error.
I have four variations on a function called ReadTextFile_XX. (XX
representing the four variations.) Each of them reads the file into a
large buffer and then parses it into a structure containing, among
other things, an array of strings. One for each line of the file.
The variations involve character size, 8-8, 8-16, 16-8, 16-16.
A pointer to a callback function to display progress is passed to
each of them. If it's NULL, the pointer is set to a stub that does
nothing, else it's left alone.
I noticed the four functions had quite a bit of redundancy (the
parts that reads the file into a large buffer were identical), so I
separated that code into a function called ReadTextFileCommon. The
entire code would be too large, so here are the highlights:
TEXTFILEDATAA is the structure.
int64 is a 64 bit int.
DWORD is an unsigned long (same as unsigned int, here).
For the callback routine.
typedef int (*RTFDPR)(int type, DWORD filecount, DWORD filesize);
The common function takes a pointer to the address of the pointer
for the callback routine because it takes care of the NULL to stub
conversion, if needed. The common function reads the file by size,
not characters. This is why filebuffer is a void pointer and
TEXTFILEDATAW can be cast to TEXTFILEDATAA because the common function
doesn't use the text-based parts of the structure.
bool ReadTextFileCommon(TEXTFILEDATAA *tfd, int64 *filesize, void
**filebuffer, void **progress);
{
RTFDPR DisplayProgress;
....
rtfdpr is the stub.
if(*progress == NULL)
*progress = rtfdpr;
DisplayProgress = *progress;
....
}
Read 8, output 16.
void ReadTextFile_AW(TEXTFILEDATAW *tfd, uint start, uint end, uint
codepage, void *progress)
{
....
Passes the address of progress to the common routine.
if(ReadTextFileCommon((TEXTFILEDATAA *)tfd, &filesize, (void
**)&filebuffer, &progress) == false)
return;
....
}
Read 16, output 16.
void ReadTextFile_WW(TEXTFILEDATAW *tfd, uint start, uint end, void
*progress)
....
I hadn't modified this code yet to take into account the pointer to
the address of the progress function pointer. Note no & before
progress in the call.
if(ReadTextFileCommon((TEXTFILEDATAA *)tfd, &filesize, (void
**)&filebuffer, progress) == false)
return;
....
}
The above compiles with no problems. I would expect an error when a
pointer to progress is passed instead of an address of pointer to
progress. Even though they are void pointers in the call, I assume
that void * and void** are not the same thing. Also, I don't see why
&filebuffer (which may be char * or wchar_t *) must be cast to void
**, while progress does not.
Is there something I'm missing here, or is the compiler missing the
error?
Thanks for any info.
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus
I have some code that compiles with no errors/warnings that would
seem to me to have an error.
I have four variations on a function called ReadTextFile_XX. (XX
representing the four variations.) Each of them reads the file into a
large buffer and then parses it into a structure containing, among
other things, an array of strings. One for each line of the file.
The variations involve character size, 8-8, 8-16, 16-8, 16-16.
A pointer to a callback function to display progress is passed to
each of them. If it's NULL, the pointer is set to a stub that does
nothing, else it's left alone.
I noticed the four functions had quite a bit of redundancy (the
parts that reads the file into a large buffer were identical), so I
separated that code into a function called ReadTextFileCommon. The
entire code would be too large, so here are the highlights:
TEXTFILEDATAA is the structure.
int64 is a 64 bit int.
DWORD is an unsigned long (same as unsigned int, here).
For the callback routine.
typedef int (*RTFDPR)(int type, DWORD filecount, DWORD filesize);
The common function takes a pointer to the address of the pointer
for the callback routine because it takes care of the NULL to stub
conversion, if needed. The common function reads the file by size,
not characters. This is why filebuffer is a void pointer and
TEXTFILEDATAW can be cast to TEXTFILEDATAA because the common function
doesn't use the text-based parts of the structure.
bool ReadTextFileCommon(TEXTFILEDATAA *tfd, int64 *filesize, void
**filebuffer, void **progress);
{
RTFDPR DisplayProgress;
....
rtfdpr is the stub.
if(*progress == NULL)
*progress = rtfdpr;
DisplayProgress = *progress;
....
}
Read 8, output 16.
void ReadTextFile_AW(TEXTFILEDATAW *tfd, uint start, uint end, uint
codepage, void *progress)
{
....
Passes the address of progress to the common routine.
if(ReadTextFileCommon((TEXTFILEDATAA *)tfd, &filesize, (void
**)&filebuffer, &progress) == false)
return;
....
}
Read 16, output 16.
void ReadTextFile_WW(TEXTFILEDATAW *tfd, uint start, uint end, void
*progress)
....
I hadn't modified this code yet to take into account the pointer to
the address of the progress function pointer. Note no & before
progress in the call.
if(ReadTextFileCommon((TEXTFILEDATAA *)tfd, &filesize, (void
**)&filebuffer, progress) == false)
return;
....
}
The above compiles with no problems. I would expect an error when a
pointer to progress is passed instead of an address of pointer to
progress. Even though they are void pointers in the call, I assume
that void * and void** are not the same thing. Also, I don't see why
&filebuffer (which may be char * or wchar_t *) must be cast to void
**, while progress does not.
Is there something I'm missing here, or is the compiler missing the
error?
Thanks for any info.
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus