{"id":11,"date":"2005-11-15T01:40:00","date_gmt":"2005-11-15T09:40:00","guid":{"rendered":"http:\/\/porkrind.org\/missives2\/?p=11"},"modified":"2015-02-20T23:20:46","modified_gmt":"2015-02-21T07:20:46","slug":"hardware-friendly-c-structures","status":"publish","type":"post","link":"https:\/\/porkrind.org\/missives\/hardware-friendly-c-structures\/","title":{"rendered":"Hardware friendly C structures"},"content":{"rendered":"<p>What I really want is a language that has really good structures. That is, they can represent hardware\/fixed layouts effectively.<\/p>\n<p>Say I were to enhance C (instead of designing a whole new language). I want something like this:<\/p>\n<pre><code class=\"language-c\">struct FATBoot {\r\n    uint8_t BS_jmpBoot[3];\r\n    char BS_OEMName[8];\r\n    little uint16_t BPB_BytsPerSec;\r\n    uint8_t BPB_SecPerClus;\r\n    little uint16_t BPB_RsvdSecCnt;\r\n    uint8_t BPB_NumFATs;\r\n    little uint16_t BPB_RootEntCnt;\r\n    little uint16_t BPB_TotSec16;\r\n    uint8_t BPB_Media;\r\n    little uint16_t BPB_FATSz16;\r\n    little uint16_t BPB_SecPerTrk;\r\n    little uint16_t BPB_NumHeads;\r\n    little uint32_t BPB_HiddSec;\r\n    little uint32_t BPB_TotSec32;\r\n    union {\r\n        struct { \/\/ FAT12 and FAT16 only:\r\n            uint8_t BS_DrvNum;\r\n            uint8_t BS_Reserved1;\r\n            uint8_t BS_BootSig;\r\n            little uint32_t BS_VolID;\r\n            char BS_VolLab[11];\r\n            char BS_FilSysType[8];\r\n        };\r\n        struct { \/\/ FAT32 only:\r\n            little uint32_t BPB_FATSz32;\r\n            little uint16_t BPB_ExtFlags;\r\n            little uint16_t BPB_FSVer;\r\n            little uint32_t BPB_RootClus;\r\n            little uint16_t BPB_FSInfo;\r\n            little uint16_t BPB_BkBootSec;\r\n            uint8_t BPB_Reserved[12];\r\n            uint8_t BS32_DrvNum;\r\n            uint8_t BS32_Reserved1;\r\n            uint8_t BS32_BootSig;\r\n            little uint32_t BS32_VolID;\r\n            char BS32_VolLab[11];\r\n            char BS32_FilSysType[8];\r\n        };\r\n    };\r\n    align(510)\r\n        little uint16_t BS_FATMagic;\r\n};\r\n<\/code><\/pre>\n<p>I picked this structure because I was unable to represent it in my fat C code because of the crazy alignment. The only thing new yet is the &#8220;little&#8221; and &#8220;align&#8221; keywords to specify endian, and alignment\/offset respectively. You would probably end up using typedefs like &#8220;luint16_t&#8221; instead of &#8220;little uint16_t&#8221;. &#8220;big&#8221;, of course, would also exist. If neither is specified, then you don&#8217;t care and therefore should be implementation defined.<\/p>\n<p>Then what I want is this:<\/p>\n<pre><code class=\"language-c\">{\r\n    tight FATBoot diskBoot;\r\n    loose FATBoot memBoot;\r\n    pread(fd, &amp;diskBoot, sizeof(diskBoot), 0);\r\n    memBoot = diskBoot;\r\n}\r\n<\/code><\/pre>\n<p>memboot is the structure using the alignment and endianness of the host processor (the &#8220;loose&#8221; keyword). diskBoot is the structure packed as specified and using the endian specified. The endian would be enforced so that the memory image of diskBoot would always be correct. Accessing diskBoot.BPB_TotSec32 would evaluate to the EXACT same thing as memBoot.BPB_TotSec32 but memBoot would be quicker since it doesn&#8217;t have to reverse (potentially) or read the bytes out and reconstruct the uint16 in some odd way (because of the weird alignment of the structure). This puts a lot of extra burden on structure copies when one is loose and one is tight, so you would expect them to be slow&#8211;certainly not memcpy() speeds.<\/p>\n<p>You could also use &#8220;strict&#8221; and &#8220;relaxed&#8221; but &#8220;loose&#8221; and &#8220;tight&#8221; are both 5 letters. \ud83d\ude42<\/p>\n<p>Basically, I want the compiler to deal with stupid endianness for me. I also want my structure to not be compiler dependant. I should be able to publish the structure in my spec and it should work on all compilers and architectures. Bit fields, for instance would be specified a certain way and not be &#8220;implementation defined&#8221;. At lease the tight ones would. Loose means &#8220;implementation defined, and fast&#8221;. Tight means &#8220;standards defined, but possibly slower&#8221;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What I really want is a language that has really good structures. That is, they can represent hardware\/fixed layouts effectively.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6,3],"tags":[14],"class_list":["post-11","post","type-post","status-publish","format-standard","hentry","category-hardware","category-software","tag-c"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/11","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/comments?post=11"}],"version-history":[{"count":6,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/11\/revisions"}],"predecessor-version":[{"id":500,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/11\/revisions\/500"}],"wp:attachment":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/media?parent=11"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/categories?post=11"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/tags?post=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}