Date: 19 Apr 1999 17:30:11 +0200 From: Dag-Erling Smorgrav <des@ifi.uio.no> To: hackers@FreeBSD.ORG Subject: [ifi.test.boa] [comp.std.c] Re: coding style advice ... really source & binary constraints Message-ID: <xzpg15wzkzg.fsf@gladsheim.ifi.uio.no>
next in thread | raw e-mail | index | archive | help
Thought this might interest some of you guys. DES -- Dag-Erling Smorgrav - des@ifi.uio.no ------- Start of forwarded message ------- From: mash@mash.engr.sgi.com (John R. Mashey) Newsgroups: ifi.test.boa Subject: [comp.std.c] Re: coding style advice ... really source & binary constraints Date: 14 Apr 1999 21:51:48 +0200 Organization: Silicon Graphics, Inc. Message-ID: <7f2rkg$3h2$1%murrow.corp.sgi.com@ifi.uio.no> References: <7dvdbl$4tp$1@shade.twinsun.com> <7e1uer$c4e$1@shade.twinsun.com> <YO7N2.1116$7K6.179543@ptah.visi.com> <7e3704$cgm$1@shade.twinsun.com> <TqaN2.1147$7K6.183694@ptah.visi.com> <t81zhzo186.fsf@discus.anu.edu.au> <3712688E.4A921D21@technologist.com> <37127362.A1EF701F@wizard.net> <3714BBB1.EE94C780@technologist.com> There still seems to be a lot of confusion arounbd portability, consistency, and data types whose sizes may be different in different implementations, and at least some of the statements in this thread have over-stated or mis-stated some of the cases. Suppose you start with code that is clean, portable, and self-consistent, but consider the different kinds of contraints that may be placed on any given data declaration: 1) INTERNAL CONSISTENCY Internal consistency inside an application or app suite, i.e., that it is the "right size" in relationship to other sizes. Most of the discussions here focus on issues around this kind of consistency. [There are, of course, plenty of programs that don't do binary I/O, don't have device dependencies, and port cleanly to almost any of the programming models.] One uses char, short, int long, long long, pointer, etc, preferably indireclty through typedefs. One might use fastest and least types. Direct use of exact-sized datatypes ought to be avoided. 2) EXTERNAL, IMMUTABLE CONSTRAINTS Consistency with external, immutable constraints set by: 2a) Hardware 2b) External network protocols 2c) Binary file interfaces external to an application suite These are 100% not under your control, and where exact-size datatypes are natural and appropriate, and where problems get caused by use of data types whose size might get changed. 3) INDUCED CODE-LOCK Binary consistency with other software interlinked with this software: 3a) Library binary interfaces, i.e., code interfaces. You may start with perfectly-portable source code for apps and libraries, that in fact can be compiled under various memory models, but once you have done this and established an environment, if you want to change the size of almost anything, you have to create an entire new parallel environment, or else do certain kinds of additions: a) This is why people with ILP32 converted to ILp32LL, rather than changing the sizeof long there, and then, for 64-bit CPUs, added entire complete LP64 environments alongside. b) This is why the Large File Summit *added* off64_t, lseek64, etc, rather than changing the size of off_t. 4) INDUCED DATA-LOCK Binary consistency with other software on same machine, possibly at different times, induced by data issues. 4a) Shared-memory 4b) Non-transient binary files For 4a), people occasionally create application suites where some executables are 32-bit and a few that have both 32- and 64-bit versions, and maybe use shared-memory for fast communication. This requires care in the definition of structs that are used from both sides. For example, to go from an ILP32LL to mixed ILP32LL/LP64 environment, one would want to do things like eliminating any direct long specifications in favor of ints, or better, typdefs that are mapped appropriately. You will have to be careful with pointer definitions, if any. 4b) It is imprecise to claim there is a problem in using variably-sized data types when writing to binary files. There is no problem if the binary files are transient temp files used inside one program, or a suite of programs that may always be recompiled together. There are plenty of program suites where one program reads data from the outside world, then gets it into an internal format that many other codes use, and this works fine. The problem arises when the code is recompiled with a different model and expected to read the existing data. For example, if you have a set of utilities for manipulating object files, doen in ILP32LL, and you used longs in those structs, you will probably be unhappy if you just recompile to LP64 [and in fact, most people's tools are still ILP32LL, even when dealing with LP64 object files.] In summary, 1) There are internal data items whose sizes can be chsoen for speed, portability, etc, and mainly need to be consistent as a group, and are fairly portable. 2) There are data sizes set by external constraints that are simply immutable, and you have must have exact descriptions of what's out there, preferably using exact types to make this absolutely clear. The issue of course, is the size relationships of these items to those in 1). 3) In portable code, some data items may have different sizes in different environments, but once you instantiate code in one environment, the sizes are locked down, in that environment, and you can't make a different choice until you can acquire an entire new environment with a consistent set of sizes. 4) There are data sizes where you start with portable code, but you create data whose sizes propagate into permanent data, and even if you acquire an entire additional environment (like LP64), there are binary interfaces that persist, and you will have to look carefully at any structures that describe the interfaces, and you will find yourself wanting typedefs that either convert to exact types, or equivalent, and of course, you will have to look at consistency between structs that go outside, and internal consistency. Note the difference between 2) where exact types are good, and 1), and even 3), where exact types should probably mostly be avoided, and 4), where they should be avoided, except sometimes in interface definitions. In almost all cases, Microsoft-like advice actually works: hardly ever use the base data types directly, use typedefs, and understand the constraints likely to be faced by them. -- -john mashey DISCLAIMER: <generic disclaimer: I speak for me only...> EMAIL: mash@sgi.com DDD: 650-933-3090 FAX: 650-933-4392 USPS: Silicon Graphics/Cray Research 40U-005, 2011 N. Shoreline Blvd, Mountain View, CA 94043-1389 ------- End of forwarded message ------- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpg15wzkzg.fsf>