ned@ghostwheel.UUCP (Ned Nowotny) (04/15/88)
At one time, C was an elegant, though imperfect, language. The language itself was purely control flow and data definition. Now, however, X3J11, in the interest of runaway optimization, has exploded the name space of the language by reserving a whole host of function, macro, and data names. While it is true that almost everyone wants standard libraries with their C compilers which match the libraries developed over the years on systems running the various flavors of Unix, I can't believe a majority of C programmers want these library definitions rolled into the language. ANSI C looks more like Pascal, Ada, Modula (pick a number), etc. every day. Maybe we do need D or its equivalent. Or maybe, there will be two languages supported in the market place by, possibly competing, vendors -- C and ANSI-C. That's it. There are two languages involved here: ANSI-C, standardized by X3J11 (thank you), and C, not quite standardized by K&R (possibly the second edition). Perhaps this is the best of all possible worlds after all. -- Ned Nowotny (ned@ghostwheel.aca.mcc.com.UUCP)
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/15/88)
In article <152@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >Now, however, X3J11, in the interest of runaway optimization, has exploded >the name space of the language by reserving a whole host of function, macro, >and data names. While it is true that almost everyone wants standard libraries >with their C compilers which match the libraries developed over the years on >systems running the various flavors of Unix, I can't believe a majority of C >programmers want these library definitions rolled into the language. I don't believe you could have studied the proposed standard before posting this nonsense. How would "exploding the name space" possible serve the interest of "runaway optimization"? X3J11 introduced only three names that could be considered to be motivated by considerations of optimization, namely the three type qualifiers. One of them has a chance of being withdrawn next week, another's main purpose was to permit ROMable data generation, and the third's main purpose is to DISABLE optimization. As to the headers, ANSI C provides a much more controlled name space than traditional practice (which varied widely among implementations). In fact the cleanliness of this name space became a substantial issue between X3J11 and IEEE 1003.1, who were prohibited from introducing additional names via the standard headers. The library functions that are being standardized for use in hosted environments are the ones that in fact programmers have wanted to have available everywhere, rather than having to carry around their own private libraries (which would not be able to implement good system interfaces in a portable manner anyway). There have been a few new functions created in order to support programming in an "internationalized" environment, but the vast majority were based on common (but not universal) existing practice. In fact my pre-ANSI C applications depend on the availability of most of these library functions; I'll be glad to have them become universally available. Definitions such as those in <limits.h> (which is NOT an X3J11 invention) only take effect if you include the header, and in any case the totality of the standardized symbols is relatively small and well-defined. Since there are no vendor-specific symbols (other than a few special forms that can be easily avoided) defined by including standard headers in an ANSI C conforming environment, there is much less to worry about when developing maximally portable applications. Anyone who has ported many applications across widely divergent C environments should be able to appreciate what an improvement this will be! If you really want a "free-standing" environment (free of library functions), that is one of the two environments provided for in the standard.
jss@hector.UUCP (Jerry Schwarz) (04/20/88)
In article <152@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: > >Now, however, X3J11, in the interest of runaway optimization, has exploded >the name space of the language by reserving a whole host of function, macro, >and data names. While it is true that almost everyone wants standard libraries >with their C compilers which match the libraries developed over the years on >systems running the various flavors of Unix, I can't believe a majority of C >programmers want these library definitions rolled into the language. > What the dpANSI standard does is limit implementors in the names they can remove from the user name space. This is not an explosion of the name space, but a control of it. In the past many implementations would give core dumps when the user wrote void write(n) int n ; { printf("%d\n",n) ; } because "printf" called "write". This will no longer be allowed. Jerry Schwarz Bell Labs, Murray Hill
ned@ghostwheel.UUCP (Ned Nowotny) (04/21/88)
In article <7691@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <152@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >>Now, however, X3J11, in the interest of runaway optimization, has exploded >>the name space of the language by reserving a whole host of function, macro, >>and data names. > >I don't believe you could have studied the proposed standard before posting >this nonsense. How would "exploding the name space" possible serve the >interest of "runaway optimization"? Of course, the newly "reserved" function, macro, and data names are reserved primarily to support portability. However, there have been more then a few comments in this newsgroup supporting the idea that "optimizing" compilers should recognize standard functions like strcpy() and replace their invocation with "semantically equivalent" in-line code. Treating strcpy(), or any other standard library function, in this manner effectively adds these functions to the implementation's set of keywords. While standardizing the library functions and header files is a positive boon to portability, implementors should not take X3J11's reservation of these element names as a license to roll the handling of functions or macros which match the standard names into the compiler. When portability is not an issue, a programmer should be free to use his or her own implementation of a standard library function. Frankly, an "optimizing" link editor which could inline short functions based on metrics provided by the programmer would be preferable. Such a link editor would also be less likely to link in "dead" code and could possibly obviate the need for prototypes if sufficient information was provided in the symbol tables generated by the compiler. (At least, we might be able to get away from the maintenance problem caused by effectively requiring multiple declarations of the same function.) -- Ned Nowotny (ned@ghostwheel.aca.mcc.com.UUCP)
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/24/88)
In article <154@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >When portability is not an issue, a programmer should be free to use >his or her own implementation of a standard library function. I think you need to explain why this is considered desirable. Many of the library functions are likely to have secret internal interfaces to others, so you cannot implement them correctly in a portable application. Others, such as strcpy(), will be implemented more efficiently in general in the standard library than in your application. If you try to speed them up by providing subset functionality, you may break other library routines that need to use these with full functionality. Whenever the C library is inappropriate, you should code for the "freestanding" environment rather than the "hosted" environment. Then you can define almost all functions as you see fit without breaking anything. Of course you may wish to steal some functions from the hosted-environment library, but whether or not that will work depends on details of the specific implementation, among other things.
drs@bnlux0.bnl.gov (David R. Stampf) (04/25/88)
In article <7750@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <154@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >>When portability is not an issue, a programmer should be free to use >>his or her own implementation of a standard library function. > >I think you need to explain why this is considered desirable. > >Many of the library functions are likely to have secret internal >interfaces to others, so you cannot implement them correctly in a >portable application. Others, such as strcpy(), will be implemented >more efficiently in general in the standard library than in your >application. If you try to speed them up by providing subset >functionality, you may break other library routines that need to use >these with full functionality. > Even when portability is and issue - I think that the C view of libraries is meant to be taken advantage of! I have frequently found the need to chuck some of the standard library routines in favour of locally written routines - more often that not, these are the memory allocation routines. Sometimes it is to gain a *huge* performance gain (in one example I didn't need the full generality that malloc gave me, since I was always allocating fixed length blocks, so I wrote my own that took advantage of the machine that I was running on (Mac) and other times it is to take advantage of some unique aspect of the machine that I was working on (parallel processing with shared memory). In either case, I wanted the code to be portable to { wide variety of machines that may have very different architectures. Those machines may pay a performance penalty, but not the ultimate penalty of having to rewrite bizarre library routines. In these cases, you cannot export your custom library routines - but have to allow the default library to kick in. (It also makes debugging a *lot* easier in most cases). < dave.
dave@sdeggo.UUCP (David L. Smith) (04/26/88)
In article <7750@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <154@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: > >When portability is not an issue, a programmer should be free to use > >his or her own implementation of a standard library function. > > I think you need to explain why this is considered desirable. The one that I have seen most commonly is a replacement malloc() routine. For example, the Bourne shell replaces malloc() with its own version so that it can have a stack interspersed with the heap. Whether or not this was necessary I'm not sure, but it does seem like the easiest way to implement it. The stack is set at the top of memory; when it grows to big it generates a segmentation violation which causes malloc() to allocate more memory and relocate the stack at the top of memory. The other alternative, if implemented with vanilla malloc, would be to give some memory to the stack and then monitor it everytime something was put on the stack to make sure it didn't overflow. Relying on the system to tell you when you're out of space is a lot easier. The Bourne shell's malloc() also provides a good reason not to replace library routines with your own lightly. In at least one version of sh (I believe it is the V.2 version), it doesn't work quite right. If this malloc() package had been used more extensively (as the library routines are) this bug wouldn't have existed for long. (BTW, the Celerity version of sh has this fixed, plug, plug :-) ) Doug mentions "hidden interfaces" between library routines. These don't sound like a good idea and probably should be avoided. After all, occasionally library routines have bugs in them which the vendor is unwilling or unable to fix. A binary-license site with a smart programmer can come up with a functional replacement for a library routine, sans bug, but not if these hidden interfaces exist. In short, I feel that being able to replace library routines is necessary for two reasons: To achieve a difference in functionality without recoding the rest of the library routines which depend on the one you want to change and to fix bugs when you don't have a source license. -- David L. Smith {sdcsvax!jack,ihnp4!jack, hp-sdd!crash, pyramid, uport}!sdeggo!dave sdeggo!dave@amos.ling.edu Sinners can repent, but stupid is forever.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/27/88)
In article <195@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes:
-Whether or not this was necessary I'm not sure, but it does seem
-like the easiest way to implement it. The stack is set at the top
-of memory; when it grows to big it generates a segmentation violation
-which causes malloc() to allocate more memory and relocate the stack
-at the top of memory. The other alternative, if implemented with
-vanilla malloc, would be to give some memory to the stack and then
-monitor it everytime something was put on the stack to make sure it
-didn't overflow. Relying on the system to tell you when you're
-out of space is a lot easier.
It also doesn't work right on some systems such as MC68000s.
Several of us spent a lot of time getting this fixed, and the BRL
version of the Bourne shell can be configured to take the tedious
but correct approach instead of relying on the SIGSEGV kludge.
I think it serves as a good illustration of what can go wrong with
preempting library routines rather than cooperating with them.
karl@haddock.ISC.COM (Karl Heuer) (04/27/88)
In article <195@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes: >>In article <154@ghostwheel.UUCP> ned@ghostwheel (Ned Nowotny) writes: >>>When portability is not an issue, a programmer should be free to use >>>his or her own implementation of a standard library function. I don't see that there's any problem. In K&R C, one can replace a library function, and the result is not portable. In ANSI C, this continues to be true. No doubt some vendors will continue to supply implementations which will do what you expect even in the face of such a construct. >The one that I have seen most commonly is a replacement malloc() >routine. For example, the Bourne shell replaces malloc() with its >own version so that it can have a stack interspersed with the heap. And it's a pain trying to port sh to implementations that don't conform to its bogus assumptions. I've been there. >Doug mentions "hidden interfaces" between library routines. These >don't sound like a good idea and probably should be avoided. Let's consider the simple kind of "hidden interface". On one implementation, printf() works by calling fputc(). On another, it doesn't. Both are correct, and hence the result of writing your own fputc() is undefined. If you don't like that situation, you'd have to specify which implementation is illegal. This would be an otherwise-unnecessary restriction on the implementor, and I don't think it's justifiable. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
simon@its63b.ed.ac.uk (ECSC68 S Brown CS) (04/27/88)
In article <195@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes: >>In article <7750@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > >The one that I have seen most commonly is a replacement malloc() >routine. For example, the Bourne shell replaces malloc() with its >own version so that it can have a stack interspersed with the heap. > >Whether or not this was necessary I'm not sure, but it does seem >like the easiest way to implement it. The stack is set at the top >of memory; when it grows to big it generates a segmentation violation >which causes malloc() to allocate more memory and relocate the stack >at the top of memory. The other alternative, if implemented with >vanilla malloc, would be to give some memory to the stack and then >monitor it everytime something was put on the stack to make sure it >didn't overflow. Relying on the system to tell you when you're >out of space is a lot easier. > This "relying on the system" technique isn't really the main reason why sh has it's own malloc - after all, on 68000-based systems, growing-on-sigsegv doesn't work anyway, but sh still needs it's own malloc there. The real reason for it is that it provides the possibility of "open-ended" malloc'ing, where you don't know how much space is required at the time when you call malloc. For example, p = q = open_ended_malloc(); while (something()) *q++ = blob(); close_malloc(q); will give you a pointer "p" pointing to everything you put on, up to the call of close_malloc(). It certainly beats having to do it all with unpleasant linked-lists all the time. I'm surprised no other programs use this technique, it seems so useful! Simon. -- -------------------------------------------------- | Simon Brown | | Laboratory for Foundations of Computer Science | | Department of Computer Science | | University of Edinburgh, Scotland, UK. | -------------------------------------------------- UUCP: uunet!mcvax!ukc!lfcs!simon ARPA: simon%lfcs.ed@nss.cs.ucl.ac.uk JANET: simon@uk.ac.ed.lfcs
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (04/27/88)
In article <195@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes: >In article <7750@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: >> In article <154@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >> >When portability is not an issue, a programmer should be free to use >> >his or her own implementation of a standard library function. >> >> I think you need to explain why this is considered desirable. > >The one that I have seen most commonly is a replacement malloc() >routine. For example, the Bourne shell replaces malloc() with its I proposed to dpANS that the library be broken into "sections" which were independent. That is you could assume that anything in one section used only documented calls to anything in another section, but there was an assumption that if you changed anything in one section that you might have to replace all of it. As I recall I wanted to separate the math, io, and a few other sections. I don't remember the discussion, but the idea was not adopted at that time. My desire is to replace print with something which doesn't take up a lot of space for F.P. routines if I will call it only with integers. Suggestions to the contrary, this would reduce the size of the program, and putting in explicit error messages would make it grow as large as the math routines (in many cases). I just renamed my routine and use a #define print my_print to generate the calls. This leaves the code easily portable. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
tps@chem.ucsd.edu (Tom Stockfisch) (04/28/88)
In article <474@bnlux0.bnl.gov> drs@bnlux0.UUCP (David R. Stampf) writes: >>In article <154@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >>>When portability is not an issue, a programmer should be free to use >>>his or her own implementation of a standard library function. >I have frequently found the need to chuck some of the standard library >routines in favour of locally written routines... >(in one example I didn't need the full generality that malloc >gave me, since I was always allocating fixed length blocks, so I wrote my own >that took advantage of the machine that I was running on (Mac)... Why would you want to call a function "malloc()" if it does not do the same thing that the malloc(3) man page says malloc() does? >... I wanted the >code to be portable to a wide variety of machines that may have very different >architectures... >In these cases, you cannot export your custom library routines - but have to >allow the default library to kick in. > < dave. So write something like # ifdef MAC BLOCK_T * /* new memory */ block_alloc( nblocks ) { [fast, unportable stuff here] } # else BLOCK_T * /* new memory */ block_alloc( nblocks ) { return (BLOCK_T *)malloc( nblocks*sizeof(BLOCK_T) ); } # endif I would find it *very* confusing to read code in which malloc() (or any other standard library function) did something besides/instead of what it is supposed to. -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
nevin1@ihlpf.ATT.COM (00704a-Liber) (04/28/88)
In article <195@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes: >In short, I feel that being able to replace library routines is >necessary for two reasons: To achieve a difference in functionality >without recoding the rest of the library routines which depend on the >one you want to change and to fix bugs when you don't have a source >license. I disagree with both these reasons. First, by replacing a library routine with your own you might still have to recode the rest of the library routines which depend on the one you want to change. Although your programs should make the assumption that they can only be dependent on the *description* of a library and independent of its' implementation, the implementor of the library routine is not bound by these restrictions. Also, you get name-space violations (how does cc know which function to call? Should it always call the new one?? If you define a third one, which one should we call??) and will very likely have problems using shared libraries. Point 2: If you want to change library routines for your program only, use statements like #define strcpy(s1, s2) my_string_copy(s1, s2) which makes this very explicit, and you don't need a source license. -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
markb@sdcrdcf.UUCP (Mark Biggar) (04/28/88)
In article <193@chem.ucsd.EDU> tps@chem.ucsd.edu (Tom Stockfisch) writes: >In article <474@bnlux0.bnl.gov> drs@bnlux0.UUCP (David R. Stampf) writes: >>>In article <154@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >>>>When portability is not an issue, a programmer should be free to use >>>>his or her own implementation of a standard library function. >>I have frequently found the need to chuck some of the standard library >>routines in favour of locally written routines... >>(in one example I didn't need the full generality that malloc >>gave me, since I was always allocating fixed length blocks, so I wrote my own >>that took advantage of the machine that I was running on (Mac)... >Why would you want to call a function "malloc()" if it does not do the >same thing that the malloc(3) man page says malloc() does? > >I would find it *very* confusing to read code in which malloc() (or any >other standard library function) did something besides/instead of what >it is supposed to. Actually malloc is a case where rolling your own can provide emormous speed up in your program. Do you realize just how much overhead is added to malloc just so you can free things. I wrote a large (20000 lines) program that used malloc everywhere. The longer it ran the slower it got. On profiling it I discovered that the program was spending 47% of its time in malloc! The program never freed anything, so I replaced malloc with a much simpler one that just gave me some memory and didn't do any of the screwy thing that the regular malloc does (like chase down a link list of every block ever allocated to see if you might just have freed a block big enough to honor the the current request). This gave me a 40%+ speedup in the program and the program stopped getting slower. By putting the simple replacement malloc in its own file, I made the program just as protable as befor because you didn't have to use my malloc. (Altough mine would work correctly on both bsd and SV type unix systems.) Mark Biggar {allegra,burdvax,cbosgd,hplabs,ihnp4,akgua,sdcsvax}!sdcrdcf!markb markb@rdcf.sm.unisys.com
bright@Data-IO.COM (Walter Bright) (04/29/88)
In article <10604@steinmetz.ge.com> davidsen@kbsvax.steinmetz.UUCP (William E. Davidsen Jr) writes:
< My desire is to replace print with something which doesn't take up a
<lot of space for F.P. routines if I will call it only with integers.
<Suggestions to the contrary, this would reduce the size of the program,
< I just renamed my routine and use a
< #define print my_print
<to generate the calls. This leaves the code easily portable.
The technique I use is to:
o Make the floating point formatting portion of printf() an internal
function call in a separate file.
o Collect all the names of floating point functions, such as
ecvt(), atof(), _dblmul(), etc.
o Define all these names in a new module called intonly.c, and have
them all resolve to a function which prints an error message and
exits.
o Therefore, when linking, including intonly.obj in the object list
will produce an integer-only program without the overhead of all
those floating point routines.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/29/88)
In article <474@bnlux0.bnl.gov> drs@bnlux0.UUCP (David R. Stampf) writes: >(in one example I didn't need the full generality that malloc >gave me, since I was always allocating fixed length blocks, so I wrote my own >that took advantage of the machine that I was running on (Mac) ... The correct way to do this is to write your own MyAlloc() function that calls on the library malloc() to obtain big chunks of heap which it then subdivides. You have no way of knowing what one of the C library routines may need to malloc(), so it is a mistake to replace malloc() with one that does not have the full semantics. On unusual architectures it is a mistake to replace it, period.
drs@bnlux0.bnl.gov (David R. Stampf) (04/30/88)
In article <193@chem.ucsd.EDU> tps@chem.ucsd.edu (Tom Stockfisch) writes: >In article <474@bnlux0.bnl.gov> drs@bnlux0.UUCP (David R. Stampf) writes: >>>In article <154@ghostwheel.UUCP> ned@ghostwheel.aca.mcc.com.UUCP (Ned Nowotny) writes: >>>>When portability is not an issue, a programmer should be free to use >>>>his or her own implementation of a standard library function. > >>I have frequently found the need to chuck some of the standard library >>routines in favour of locally written routines... >>(in one example I didn't need the full generality that malloc >>gave me, since I was always allocating fixed length blocks, so I wrote my own >>that took advantage of the machine that I was running on (Mac)... > >Why would you want to call a function "malloc()" if it does not do the >same thing that the malloc(3) man page says malloc() does? > Of course I wouldn't want to define a function called printf that allocates memory, or sin that did sqrt. The point is that one might like to have a more efficient version (for the application at hand) than the malloc provided in the library. My versions of malloc *always* behaved exactly like the malloc(3). It might be totally acceptable to have a routine called emalloc() or must_malloc() or some such that *must* allocate memory and in facts checks the return value for you. >>... I wanted the >>code to be portable to a wide variety of machines that may have very different >>architectures... >>In these cases, you cannot export your custom library routines - but have to >>allow the default library to kick in. >> < dave. > >So write something like > > # ifdef MAC > BLOCK_T * /* new memory */ > block_alloc( nblocks ) > { > [fast, unportable stuff here] > } > # else > BLOCK_T * /* new memory */ > block_alloc( nblocks ) > { > return (BLOCK_T *)malloc( nblocks*sizeof(BLOCK_T) ); > } > # endif > This is better??? I find it 1) ugly, 2) error prone (when you start to write code for two different machines using ifdefs, there is a tendency to debug only one branch of the #ifdef and leave the other for some other character to find) and 3) makes the malloc version even less efficient - now you make 2 function calls per malloc rather than one. Finally, when the programmer is working on a remote section of the code he is likely to either forget about this function and call malloc, forget what the new program was called, or see a reference to block_malloc, and not really associated the malloc function with it. Also, it is very unlikely that a programmer would go to the trouble of making a new manual page for block_malloc. >I would find it *very* confusing to read code in which malloc() (or any >other standard library function) did something besides/instead of what >it is supposed to. >-- > >|| Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu Me too. That's why I would want it to perform the save function as malloc, only to do it in a slightly different fashion. < dave *fodder for the news program * *fodder for the news program * *fodder for the news program * *fodder for the news program * *fodder for the news program * *fodder for the news program * *fodder for the news program * *fodder for the news program * *fodder for the news program *
bts@sas.UUCP (Brian T. Schellenberger) (05/02/88)
There have been numerous postings back and forth about whether or not one should replace library routines. It seems to me to be much easier to get the legitimate benifits of such replacement, assuming there are any, without being unportable than most people seem to assume. First of all, it is clearly unportable and dangerous to replace the versions of the library routines used by other library routines, since there is no way to know what the inter-relationships of these routines may be on various machines. This doesn't preclude you from doing whatever you want if the code is for a single machine and single version of the compiler and operating system, but in such a case portable code (and the ANSI draft) should be of no concern anyway. Second of all, if you don't like the normal memory allocation routines, you can write and use your own quite portably. Third, if you *really* can't stand to change the name by which you call the routines, it is pretty safe to #define malloc mymalloc Of course, strictly speaking, the ANSI draft states that all library routine names are reserved words, so this might be unportable (though I doubt it will really fail anyplace). So it would be safer to retrain your fingers to type "myalloc" instead of "malloc". If you want it to be the same even on machines whose native "malloc" you like, simply #if I_LIKE_IT #define myalloc malloc #endif -- --Brian. (Brian T. Schellenberger) ...!mcnc!rti!sas!bts . . . now at 2400 baud, so maybe I'll stop bothering to flame long includes.
ok@quintus.UUCP (Richard A. O'Keefe) (05/03/88)
In article <488@sas.UUCP>, bts@sas.UUCP (Brian T. Schellenberger) writes: > First of all, it is clearly unportable and dangerous to replace the versions > of the library routines used by other library routines... Sometimes that is exactly what you want. For example, what is the good of replacing the malloc() family by something with the same interface but a much better implementation if this doesn't catch malloc() calls from stdio? If you _don't_ want to catch library calls, there isn't any need to REdefine any library function. But yes, it is non-portable, and can be dangerous (it's usually ok under UNIX and more trouble than it's worth under VMS). It's worth noting that exactly this technique is an offical part of the System V library interface (see 'matherr'). A library _could_ be structured into "facilities" (malloc, stdio, math, signal&longjmp, ...) such that each facility was defined to use only the public interface of the other facilities. It would then be safe to replace an entire facility with your own code. There is nothing in the dpANS to prohibit a vendor doing this; code which relied on a well-structured library would be non-portable but no longer dangerous.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/03/88)
In article <488@sas.UUCP> bts@sas.UUCP (Brian T. Schellenberger) writes: >Second of all, if you don't like the normal memory allocation routines, you >can write and use your own quite portably. The only safe way to do this is to make your private memory allocator obtain heap space from the standard C library allocator (malloc).
gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/03/88)
In article <924@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >It's worth noting that exactly this technique is an offical part of the >System V library interface (see 'matherr'). matherr() was intended to be replaced by user code (and so documented) as a deliberate aspect of its design. None of the other library routines is obliged to support such perversion.
nevin1@ihlpf.ATT.COM (00704a-Liber) (05/04/88)
In article <924@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >In article <488@sas.UUCP>, bts@sas.UUCP (Brian T. Schellenberger) writes: >> First of all, it is clearly unportable and dangerous to replace the versions >> of the library routines used by other library routines... >Sometimes that is exactly what you want. For example, what is the good of >replacing the malloc() family by something with the same interface but a >much better implementation if this doesn't catch malloc() calls from stdio? Suppose there are two routines: malloc() and _malloc(). malloc() is the routine for heap allocation for both internal library calls and external (programmer) calls. _malloc() is strictly for internal library use only (for example: maybe malloc() does some checking of the heap while _malloc() just does the allocating). You come along and replace malloc() with your own function. The library routines that call malloc() are caught while the ones that call _malloc() aren't. There is no way for you to know whether or not you have replaced _all_ the calls to the malloc family. >A library _could_ be structured into "facilities" (malloc, stdio, math, >signal&longjmp, ...) such that each facility was defined to use only the >public interface of the other facilities. It would then be safe to >replace an entire facility with your own code. There is nothing in the >dpANS to prohibit a vendor doing this; code which relied on a well-structured >library would be non-portable but no longer dangerous. Yes, but there is nothing in dpANS which _requires_ this. Nor do I think it should be required. If a compiler writer decides to hand code in assembler all the library routines so that it produces the tightest, fastest possible code he should be allowed to do so (in which case internal subroutines may only be assembler JMP statements which do not have nearly as much overhead as normal C function calls). -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
ok@quintus.UUCP (Richard A. O'Keefe) (05/05/88)
In article <7821@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: : In article <924@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: : >It's worth noting that exactly this technique is an offical part of the : >System V library interface (see 'matherr'). : : matherr() was intended to be replaced by user code (and so documented) : as a deliberate aspect of its design. None of the other library routines : is obliged to support such perversion. Yes, I know that. I guess it's a mistake to try to be too succinct in news. matherr() is a compellingly good(bad) example of how _not_ to design an error-handling interface. I thought I should provide some argument against replacing library routines as well as some for.
ok@quintus.UUCP (Richard A. O'Keefe) (05/05/88)
In article <4626@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes: > >A library _could_ be structured into "facilities" (malloc, stdio, math, > >signal&longjmp, ...) such that each facility was defined to use only the > >public interface of the other facilities. > Yes, but there is nothing in dpANS which _requires_ this. Nor do I think > it should be required. I did not say that the dpANS requires it, or that it should require it, or that anyone should require it. I merely outlined a scheme which _would_ make it safe for users to replace library facilities. The scheme is nothing more than good software engineering practice. I don't know whether any C implementation actually does that (at least the version of UNIX I'm using doesn't have a hidden _malloc()). > If a compiler writer decides to hand code in > assembler all the library routines so that it produces the tightest, > fastest possible code he should be allowed to do so. (in which case internal > subroutines may only be assembler JMP statements which do not have nearly > as much overhead as normal C function calls). He should also be allowed to go broke. I'd much rather he spent his time figuring out how to make _my_ code go fast. I would be _especially_ forgiving to a compiler writer who had decided to put the effort into making normal C function calls fast. [e.g. special treatment for leaf functions, maybe even #pragma inline(...).]