From: Patricia Shanahan on 7 Dec 2009 15:24 BGB / cr88192 wrote: > "Patricia Shanahan" <pats(a)acm.org> wrote in message > news:gPqdncAsILnoyoDWnZ2dnUVZ_tudnZ2d(a)earthlink.com... >> BGB / cr88192 wrote: >> ... >>> for example, pointer arithmetic, ... is just another part of the job... >> This, to my mind, is the very worst thing about C. >> >> I have seen far too many hard-to-debug operating system bugs due to >> widespread pointer arithmetic. It would be far better if C pointer >> arithmetic were constrained to conform to the standard. That way, when a >> data structure gets clobbered the code doing the clobbering would have >> to be something related to the data structure. >> > > bit, it is also essential to pull off many of the things C is able to do. > otherwise, people would have to resort to assembler to do these things... Option 1: Maintain hundreds of thousands of lines of source code any one of which could corrupt any data structure. Option 2: Maintain hundreds of thousands lines of source code with limited, controlled access to data structures, and a few assembly language functions to do specific jobs such as turning the address calculated by a memory allocator into a pointer. I have spent plenty of time coping with option 1 in UNIX-derived operating systems. I can't help thinking that option 2 might be easier. Patricia
From: Chris M. Thomasson on 7 Dec 2009 16:13 "Chris M. Thomasson" <no(a)spam.invalid> wrote in message news:pQcTm.40557$ZF3.34691(a)newsfe13.iad... > "Pascal J. Bourguignon" <pjb(a)informatimago.com> wrote in message > news:87iqciepsv.fsf(a)galatea.local... [...] >> All the pointer and bit fiddling is done in lisp in heap.lisp. > > Okay. Well, I need to study up on Lisp because the code looks a bit > foreign to me. When you get some free time, and don't mind wasting some of > it... Could you perhaps show me how to create an analog of the following > 32-bit C hack in Lisp: > _________________________________________________________________ > #include <stddef.h> > #include <assert.h> > #include <string.h> > #include <limits.h> > > > typedef char static_assert > [ > sizeof(void*) * CHAR_BIT == 32U && > sizeof(unsigned short) * CHAR_BIT == 16U && > sizeof(size_t) == sizeof(void*) ? 1 : -1 > ]; > > > #define ALIGN_UP(mp_ptr, mp_align) \ > ((void*)((((size_t)(mp_ptr)) + \ > ((mp_align) - 1U)) & ~(((mp_align) - 1U)))) > > > #define CHUNK_SIZE 0xFFFFU > #define CHUNK_MASK 0xFFFF0000U > #define META_MASK 0x0000FFFFU [...] DAMN IT ALL TO HELL!!!!!!!! Ummm, `CHUNK_SIZE' should be `0x10000U'. That's what I get for programming directly in the news reader! ARGH!!!! corrected code: ______________________________________________________________ #include <stddef.h> #include <assert.h> #include <string.h> #include <limits.h> typedef char static_assert [ sizeof(void*) * CHAR_BIT == 32U && sizeof(unsigned short) * CHAR_BIT == 16U && sizeof(size_t) == sizeof(void*) ? 1 : -1 ]; #define ALIGN_UP(mp_ptr, mp_align) \ ((void*)((((size_t)(mp_ptr)) + \ ((mp_align) - 1U)) & ~(((mp_align) - 1U)))) #define CHUNK_SIZE 0x10000U #define CHUNK_MASK 0xFFFF0000U #define META_MASK 0x0000FFFFU int main(void) { unsigned short meta; unsigned char* chunk_ptr; unsigned char raw_memory[(CHUNK_SIZE * 2U) - 1U] = { '\0' }; unsigned char* align_ptr = ALIGN_UP(raw_memory, CHUNK_SIZE); unsigned char* mutate_ptr = align_ptr + USHRT_MAX; if (! (((size_t)align_ptr) % CHUNK_SIZE)) { int x = 5; } strcpy((char*)align_ptr, "Hello World!"); chunk_ptr = (unsigned char*)(((size_t)mutate_ptr) & CHUNK_MASK); assert(chunk_ptr == align_ptr); meta = (unsigned short)(((size_t)mutate_ptr) & META_MASK); assert(meta == USHRT_MAX); assert(! strcmp((char*)chunk_ptr, "Hello World!")); return 0; } ______________________________________________________________ Sorry about that fuc%king non-sense!!!! ;^(...
From: BGB / cr88192 on 7 Dec 2009 16:49 "Patricia Shanahan" <pats(a)acm.org> wrote in message news:dsudnUK6ZPUV-YDWnZ2dnUVZ_gWdnZ2d(a)earthlink.com... > BGB / cr88192 wrote: >> "Patricia Shanahan" <pats(a)acm.org> wrote in message >> news:gPqdncAsILnoyoDWnZ2dnUVZ_tudnZ2d(a)earthlink.com... >>> BGB / cr88192 wrote: >>> ... >>>> for example, pointer arithmetic, ... is just another part of the job... >>> This, to my mind, is the very worst thing about C. >>> >>> I have seen far too many hard-to-debug operating system bugs due to >>> widespread pointer arithmetic. It would be far better if C pointer >>> arithmetic were constrained to conform to the standard. That way, when a >>> data structure gets clobbered the code doing the clobbering would have >>> to be something related to the data structure. >>> >> >> bit, it is also essential to pull off many of the things C is able to do. >> otherwise, people would have to resort to assembler to do these things... > > Option 1: Maintain hundreds of thousands of lines of source code any one > of which could corrupt any data structure. > it is nowhere near this bad in practice... the main source of problems is either ugly/hackish use of pointer math; overflowing buffers and overwriting other data. the former is addressed by using "fairly regular" means of accessing most structures (IOW: using a Java-like strategy for general usage of memory objects). the latter is a little harder, mostly relying on careful coding practices, and to a lesser extent building machinery into the memory manager to help detect and address such situations retroactively. further one can add some code to assist some in locating the offending code (usually by using heuristic measures to identify the point where the most-likely-overflowed buffer was allocated). I have not as often added the machinery needed for object-identification, since it does not come free (it would likely add at least 16 bits to the total object overhead), and possibly also a cost in terms of allocation time. > Option 2: Maintain hundreds of thousands lines of source code with > limited, controlled access to data structures, and a few assembly > language functions to do specific jobs such as turning the address > calculated by a memory allocator into a pointer. > > I have spent plenty of time coping with option 1 in UNIX-derived > operating systems. I can't help thinking that option 2 might be easier. > possibly, but note that this is also fairly close to saying that everything should be written in a language such as C# or Java... this is possible, but hardly free... of minor note: for some of my own personal uses I have a trans-compiler from JBC to C, but it is far from producing standalone code... actually, I had partly used it before in an attempt to build GNU ClassPath, but did not succeed at the time (mostly due to somewhat exceeding the amount of stuff I could put in a single DLL...), and at this point did not care enough to bother splitting up classpath into multiple DLL's (even if I did so, I would have to provide code for many of the 'native' methods, ...). (as well as my uncertainty anymore about plain GPL...). so, alas, no class library... a lighter weight and more standalone version could be possible by compiling the code in a slightly more C++ - like manner, although I suspect this would put some restrictions on the language (for example, class-layout would be fixed at compile time, ...). (it remains uncertain though as to how to best implement interfaces in this case). however, it could be more useful if I wanted to use Java in a way slightly more on-par with how I use C... > Patricia
From: Pascal J. Bourguignon on 7 Dec 2009 16:51 "BGB / cr88192" <cr88192(a)hotmail.com> writes: > my experience has been the reverse: > my HLL code has tended to be very brittle and unmaintainable in the long > term; > my C codebase has been one of the most stable parts of the codebase, with > many parts of the codebase being around or >1 decade old and still > working... This warrants a finer analysis. What would be the causes of the brittleness of your HLL code? (And what language exactly is it?) -- __Pascal Bourguignon__
From: Pascal J. Bourguignon on 7 Dec 2009 16:57
"BGB / cr88192" <cr88192(a)hotmail.com> writes: > "Patricia Shanahan" <pats(a)acm.org> wrote in message > news:gPqdncAsILnoyoDWnZ2dnUVZ_tudnZ2d(a)earthlink.com... >> BGB / cr88192 wrote: >> ... >>> for example, pointer arithmetic, ... is just another part of the job... >> >> This, to my mind, is the very worst thing about C. >> >> I have seen far too many hard-to-debug operating system bugs due to >> widespread pointer arithmetic. It would be far better if C pointer >> arithmetic were constrained to conform to the standard. That way, when a >> data structure gets clobbered the code doing the clobbering would have >> to be something related to the data structure. >> > > bit, it is also essential to pull off many of the things C is able to do. > otherwise, people would have to resort to assembler to do these things... > > so, in a way, it is a double-edged sword: > with power comes responsibility, ... > > > granted, I am not claiming that people should use it for whatever comes to > mind, as I have also seen my share of code making some fairly nasty use of > pointer arithmetic, but granted, it is just another part of the job. > > FWIW, even C# added pointers and the ability to do some C like tasks > (granted, one has to go through some amount of "red tape" to do so), and I > figure it is unlikely MS would have added anything of the sort unless there > were some good reason to do so (it is in addition to the more abstract > Java-like object model). This "red tape" is a good thing. For example, in Modula-3, each module is labelled SAFE or UNSAFE, depending on whether it uses only safe features of the language, or if it uses also unsafe features, such as pointer manipulation. Such a tagging allows to concentrate more on the verification and validation of the unsafe modules, the compiler ensuring that the safe modules are good. Features such as type casting or pointer manipulation are "unsafe", and shouldn't be used casually. Once you have restricted them to a small number of little modules, you can rewrite all the rest in a high level safe programming language, and keep the unsafe module in C, or just use the high level safe programming language to do some metaprogramming, generating the unsafe code automatically (thus increasing its "safeness", since the code generator should be easier to prove than each occurences of unsafe code). Therefore C became useless. -- __Pascal Bourguignon__ |