Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C programming structure passed as cast to char *?

Tags:

c

I have a little problem, in a scenario where:

while (read(dp->fd, (char *) &dirbuf, sizeof(dirbuf)) == sizeof(dirbuf)) { ... }

where dirbuf is:

struct direct dirbuf { 
    ino_t d_ino; char d_name[DIRSIZ]; 
};  

How does C know to read in data contingently into our structure? With the read() Like, the alignment of our dirbuf fits perfectly as a character array? since read accepts a void * for its second argument, passing a structure as a cast to char * makes very little sense to me, how does it cater for other member elements properly?

I'm not sure if I'm even asking this question properly, I hope someone can decipher my problem behind my lunacy and help me out.

Thanks.

like image 518
wakeup Avatar asked Mar 01 '10 23:03

wakeup


2 Answers

Hysterical Raisens

Casting buffers to char * is a legacy code pattern that one sees frequently. It has been used so often that it is still typed in today, long after it ceased to be necessary.

At one point there was no void type, so an API like read(2) would declare the buffer parameter as char * and all callers would cast their data to char *.

But read(2) has been a void * for a long, long, time. It has been that long since it was necessary to have any kind of a cast at the call site.

However, the old code is still around, people still read it, and then they perpetuate the design pattern.

It doesn't do any harm.

With respect to contiguous data, one of two things is happening. Either the data structure and the type is designed to lay out densely on most or all likely machines, or a similar statement was used to write the data out in the first place so pad bytes don't matter unless the data file is to be moved between disparate architectures.

like image 100
DigitalRoss Avatar answered Sep 30 '22 00:09

DigitalRoss


It doesn't read and properly align the fields in the structure. It just takes the total size of the structure (from sizeof) and the starting address (from &dirbuf) and reads into that memory without regard to the struct declaration.

The assumption is that whatever was in the file was already properly aligned to fit in the structure.

The (char *) cast is just there to shut the compiler up. (void *) would have done just as well. Or no cast at all, since the compiler will convert pointer type to void* without casting.

like image 24
John Knoeller Avatar answered Sep 30 '22 01:09

John Knoeller