- gcc 4.7.2
- c89
bstrlib.hfrom Better String Library
I am maintaining someone’s code that looks like this:
FILE *db_fp = NULL;
bstring data = NULL;
db_fp = db_open(DB_FILE, "r");
LOG_CHECK(db_fp == NULL, "Failed to open database: %s", DB_FILE);
data = bread((bNread)fread, db_fp);
LOG_CHECK(data == NULL, "Failed to read from db file: %s", DB_FILE);
db_close(db_fp);
return data;
I am having a little trouble understanding the following line:
data = bread((bNread)fread, db_fp);
What I can guess, is that it is fetching a bstream from the following file pointer and returning a bstring. However, I am wondering about bread and fread.
bread contains 2 arguments, A function pointer (bNread) and the file pointer. But I am not sure I understand how it works.
The declaration for
bread()in the Better String Library documentation is:Therefore,
bread()is a function that takes a pointer to a function as an argument. ThebNreadtype is used to specify the type of function. Thefread()function is close enough to pass muster when cast — the match isn’t exact because it expects aFILE *for its fourth argument and a true function of the type pointed at by abNreadexpects avoid *. The second argument tobreadis the value to be passed as the fourth argument to the function pointed to by thebNread.So, in the code you’re maintaining:
The Better String Library function is called with
fread()as the I/O function, cast to the correct type to quell an otherwise justified compiler warning about a mismatch in types, plus the file stream that should be used for reading.The implementation of the
bread()function uses the function pointer and the stream pointer whenever it needs to do I/O in order to read a string. That is, as KerrekB also explained, the codemight write something like:
or (equivalently):
(If you learned C long enough ago, the first was the only way to invoke functions through pointers to functions; since the C89 standard was produced, the second has been available and is probably used more widely these days.) There are a number of tricks that the implementation must worry about, but the basic function call would be somewhat similar. The code could use I/O functions other than
fread(), though the interface to the function must be similar.Pointers to functions are powerful, but are arcane until you’ve used them.