mike@RICE.ARPA (07/05/84)
From: Mike Caplinger <mike@RICE.ARPA> I can't believe that somebody is proposing ANOTHER standard that imposes a 6-character uniqueness limit on external names! How much longer are we going to be stuck with somebody's 1960s linker implementation choice? If ANSI got real and made the names of reasonable length, maybe that would force some of these sleazy people to write a real linker! - Mike Caplinger
DBrown@HI-MULTICS.ARPA (07/05/84)
This message is empty.
gwyn@brl-tgr.UUCP (07/06/84)
More likely there will be ADAs with 6-character line length limits imposed.
henry@utzoo.UUCP (Henry Spencer) (07/08/84)
Mike Caplinger observes: I can't believe that somebody is proposing ANOTHER standard that imposes a 6-character uniqueness limit on external names! How much longer are we going to be stuck with somebody's 1960s linker implementation choice? If ANSI got real and made the names of reasonable length, maybe that would force some of these sleazy people to write a real linker! The 6-character uniqueness limit is not being "imposed" by the standard; it is already imposed by dozens of linkers in use at tens of thousands of sites. This is (a) most unfortunate, but (b) extremely hard to fix. Many, many C users work on systems which are constrained to be backwards compatible with "somebody's 1960s linker implementation choice" forever, or very nearly so. It is a fact, regrettable but unavoidable, that C programs which need more than 6-characters-monocase to distinguish among their external identifiers are not portable, period. This is not going to be changed by wishing it away. The ANSI folks have chosen to recognize this fact rather than ignore it. There is a fundamental question of standards politics here: should the standard attempt to tidy up and codify existing stuff, or should it try to change the world by inventing all kinds of new goodies? The problem with the latter approach is that it's hard to stop the standards group once they've got the bit between their teeth, and the result is often nearly unrecognizable. WE DON'T WANT THIS TO HAPPEN TO C!! Many people, including me, breathed a sigh of relief when it became clear that the ANSI C people were taking the conservative but safe path of deferring to reality rather than defying it. These things are always compromises. People in an environment with fairly controllable software will probably have either 31-character external names (consistent with the internal names) or unlimited-length external names fairly soon. Folks in environments with uncontrollable software won't be able to upgrade, and portability to such environments will remain an issue that cannot be ignored. This being the case, the ANSI C folks have chosen to write their standard in such a way that it is compatible with most existing environments, not just the fortunate few. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
dgary@ecsvax.UUCP (07/11/84)
<> >From: henry@utzoo.UUCP (Henry Spencer) Sat Jul 7 20:11:41 1984 >The 6-character uniqueness limit is not being "imposed" by the standard; >it is already imposed by dozens of linkers in use at tens of thousands >of sites. A minor point: The linker imposes a limit only on the number of significant characters in EXTERNAL names. K&R claim internal names can have 8 significant characters. I see no reason for a limit on external names to be imposed on the whole language. D Gary Grady Duke University Computation Center, Durham, NC 27706 (919) 684-4146 USENET: {decvax,ihnp4,akgua,etc.}!mcnc!ecsvax!dgary
ron@brl-tgr.ARPA (Ron Natalie <ron>) (07/12/84)
Unfortunately a lot of C/UNIX implementations don't even get this right. The trick of sticking an underscore in front of C symbols causes the eight significant characters to become nine. The assembler on the PDP-11's only had eight significant characters in the symbol names. Variables that differed only in their eighth and later characters fell through the C symbol checks and caused the assembler to blow up with funny "m" error messages. -Ron
henry@utzoo.UUCP (Henry Spencer) (07/15/84)
> A minor point: The linker imposes a limit only on the number of > significant characters in EXTERNAL names. K&R claim internal names > can have 8 significant characters. I see no reason for a limit on > external names to be imposed on the whole language. Please read my original summary more closely. The 6-character limit applies only to external names. The limit for internal names is much easier to change, and the current draft standard has it as 31 rather than merely 8. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
gwyn@BRL.ARPA (VLD/VMB) (11/22/85)
difftime() accepts time_t arguments but returns a double. Its result is expressed in SECONDS, whereas a time_t is not necessarily expressed in seconds. There is no portable way to do simple arithmetic on general time_t values to produce a time difference in seconds, hence difftime(). gmtime(), like time(), ctime(), and localtime(), takes a pointer to a time_t because that's what they already do. These functions have been defined (in UNIX at least) for a long time (no pun intended). Really, guys, the X3J11 committee has been doing a very nice job, much better than "obviously didn't put much thought into anything related to times". Seems to me they put more thought into it than some of their detractors..
gwyn@BRL.ARPA (VLD/VMB) (11/23/85)
As an X3J11 C implementor, it would be your job to arrange for the correct operation of routines such as gmtime(). This CAN be done on any non-UNIX system. 2.nBSD (for n around 3) even implemented per-user environments without kernel support. For example (not necessarily optimum), DST could be indicated by the presence of a specific system file. The implementation of gmtime() would test for this (the first time it is called within the process). I think the concept of DST is stupid, but so long as it has to be dealt with, some means must be provided.
Makey@logicon.arpa (Jeff Makey) (11/23/85)
The daylight time flag returned by localtime() does NOT have to be provided by the operating system. I looked at the 10-year-old source code on my PDP-11/70 PWB UNIX system (no environment variables) and observed that localtime() *computes* whether or not the date it is processing is between the last Sundays in April and October. The ONLY input to localtime() (it makes no system calls) is a GMT date/time value that is immediately converted to local standard time, then to daylight time if appropriate. There are static variables that are hard-coded to indicate: the difference in hours between GMT and local standard time; and whether or not conversion to daylight time should ever occur (useful throughout most of Indiana, where they are always on eastern standard time). :: Jeff Makey Makey@LOGICON.ARPA
peter@graffiti.UUCP (Peter da Silva) (11/24/85)
> I think the concept of DST is stupid, but so long as > it has to be dealt with, some means must be provided. Perhaps, perhaps, but it'd be better to leave that up to the application instead of stuffing the library or forcing some PC user to create a file at certain times of the year just to run some program that happens to be written in 'C'. In addition, the X3J11 draft I read explicitly stated time_t was a number of seconds, not a magic cookie that had to be difftime()-ed if one wanted to do comparisons. Even if it is, on other systems floating point support is relatively expensive in terms of memory, which would make difftime() an unnaceptable burden on the implementor. The basic complaint is that X3J11 is not a description of 'C', but rather a description of 'C' under UNIX. There is a good deal of stuff in it that should not be in the language definition, but rather in a standard extension: the UNIX compatibility package, for example. I like UNIX, and I'd like nothing better than to see it become the standard O/S for non real-time applications (how does one deal with the DST in some little standalone 'C' program in an RTU in Oman somewhere? They don't even use it...), but I don't expect it to happen. I like 'C', and I sure hope that it doesn't become restricted to UNIX and UNIX-like systems. That's what I see happening, however, unless X3J11 is (a) ignored or (b) fixed. And I hope that if they don't (b) fix it, everyone else follows my example and (a) ignores it. -- Name: Peter da Silva Graphic: `-_-' UUCP: ...!shell!{graffiti,baylor}!peter IAEF: ...!kitty!baylor!peter
zben@umd5.UUCP (11/26/85)
In article <468@graffiti.UUCP> peter@graffiti.UUCP (Peter da Silva) writes: In article ? ? writes: [z] >> I think the concept of DST is stupid, but so long as >> it has to be dealt with, some means must be provided. > >Perhaps, perhaps, but it'd be better to leave that up to the application >instead of stuffing the library or forcing some PC user to create a file >at certain times of the year just to run some program that happens to be >written in 'C'. ... Watch out people! The latest proposal in Congress to keep elections from being decided before the West Coast gets its chance to vote involves a bad change to Daylight Savings Time! As I read it in the Post yesterday, the proposal is to make the polling places close at 7:00 EST, 8:00 CST, and extend Daylight Savings Time for the West Coast two more weeks till election day! The idea of changing the DST algorithm for a) West Coast sites only, and b) only in an election year doesn't really turn me on AT ALL... I think this is a powerful argument for hiding the kluges in either a library routine or the system. Somewhere it can be setup when the system is configured, and not have to be replicated in hundreds of programs. If it is in the system, one would not have to rebuild programs sent from elsewhere, while if it is in the library one would at least have to re-link-edit. Let's keep our eyes on this particular snake - it just might bite us all someday... -- Ben Cranston ...{seismo!umcp-cs,ihnp4!rlgvax}!cvl!umd5!zben zben@umd2.ARPA
gwyn@BRL.ARPA (VLD/VMB) (11/27/85)
The thing is, the raw "language" part of C is (by design) insufficient for programming real hosted applications, so it must be extended with some library routines. The de facto set of library routines is a subset of those found in the UNIX C library. Certainly STDIO is generally agreed upon, but there is more interaction with the host environment needed than just file I/O. Since a large number of non-UNIX C implementations have provided much of the UNIX C library, and since most of those library routines are well-designed, it makes sense to standardize their interface, patterned after the original UNIX routines but with redefinitions as required to accommodate a wide variety of operating system environments. The Software Tools "Virtual Operating System" approach was very similar (although accessed from RatFor, not C), and their routines were also closely modeled after UNIX's. This by no means constrained implementation to just UNIX and its lookalikes; the VOS ran on just about every major operating system, from micros to mainframes. I haven't noticed any real UNIX dependencies in X3J11's proposed standard library routines. Virtually everything they have included are routines I frequently use in applications. This applies no less to my Apple //e than it does for UNIX systems. In the past I have implemented similar libraries for RT-11 and RSTS/E, and DEC's VMS C compiler provides pretty much the same functions. I agree that the C language standard should be independent of UNIX, but I think it already is. I see no point in splitting the standard up into pieces, since portable applications will require these routines anyway. With only a few very minor quibbles, I am happy with the X3J11 proposed draft standard and its general applicability to virtually any hosted environment. (Of course, your compiler vendor may have some work to do to conform, but that's true in any case.) time_t is NOT seconds, in Doc. No. X3J11/85-045 (dated April 30, 1985). It IS an "arithmetic type", which does seem like an oversight, since arithmetic on it cannot be done portably (and structures can be assigned, passed as function parameters, etc. so all necessary operations work without requiring arithmeticity). I think the oversight needs to be remedied in the final standard.
gwyn@BRL.ARPA (VLD/VMB) (11/27/85)
> "they took the entry for ctime from the third section of the UNIX > manual and copied it verbatim" Hey, get a current copy of the draft standard! Since April, the X3J11 spec for ctime has not very much resembled the one in any UNIX manual. If you want to criticize the committee's work, you ought to find out what it is first. I find that a lot of thought has indeed been put into generality of the time functions.
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (11/27/85)
> Watch out people! The latest proposal in Congress to keep elections from > being decided before the West Coast gets its chance to vote involves a bad > change to Daylight Savings Time! > > As I read it in the Post yesterday, the proposal is to make the polling > places close at 7:00 EST, 8:00 CST, and extend Daylight Savings Time for the > West Coast two more weeks till election day! Better to close the polls before they open; maybe we could get rid of the silly Congress eventually. > The idea of changing the DST algorithm for a) West Coast sites only, and > b) only in an election year doesn't really turn me on AT ALL... I think this > is a powerful argument for hiding the kluges in either a library routine or > the system. To me, it's a powerful argument for scrapping DST altogether.
laura@l5.uucp (Laura Creighton) (11/27/85)
In article <98@brl-tgr.ARPA> gwyn@BRL.ARPA (VLD/VMB) writes: > >Hey, get a current copy of the draft standard! How? I've sent electronic mail to Larry Rostler 3 times in the last 2 months. Maybe he has been busy, and maybe ihnp4 had indigestion, but I still don't have a current standard. Is there any way that the draft standard could get posted to mod.std.c? Or sent to John Quarterman (or someone, me even, but he seems a good choice so that people could tftp it)? I *hope* it exists in electronic from somewhere... -- Laura Creighton sun!l5!laura (that is ell-five, not fifteen) l5!laura@lll-crg.arpa
rbutterworth@watmath.UUCP (Ray Butterworth) (11/27/85)
> gmtime(), like time(), ctime(), and localtime(), takes a > pointer to a time_t because that's what they already do. > These functions have been defined (in UNIX at least) for a > long time (no pun intended). Simply because they have been around for a long time, doesn't mean that they are the best way of doing things; and simply because UNIX does it that way, doesn't mean that everyone else should do it that way. This is supposed to be a C standard, not a make-the-world-look-like-UNIX standard. I understand why they originally took pointers; but the need is no longer there. Now is the time to correct old mistakes not propagate them. A number of other functions are defined by the standard that differ from the same functions on UNIX (at least some versions of UNIX) and people are going to have to make a number of changes to their code anyway. It wouldn't be that difficult for the standard to define these functions with completely different names. Systems that never had the functions before can simply implement them as required, while systems that have similar functions can either provide macros or cover functions for mapping the one name and syntax into the other until the general population gets used to the new names. I know that for anything I write I already have a cover function for ctime(), so that I can use ctime(time()) without having to go through the bother of allocating a temporary variable that I can take the address of. > difftime() accepts time_t arguments but returns a double. > Its result is expressed in SECONDS, whereas a time_t is not > necessarily expressed in seconds. There is no portable way > to do simple arithmetic on general time_t values to produce > a time difference in seconds, hence difftime(). OK, this was my misreading of the standard. The problem was that it introduced CLK_TCK, clock_t, and time_t together, and it wasn't obvious to me that CLK_TCK wasn't the conversion factor between the two. I wasn't the only one that made the same mistake. There really should be a note here that the meanings of the values of time_t are implementation defined. One of the biggest problems with the K&R C manual is the things that it doesn't explicitly mention. It often takes a student of theological research to find the various hints and put them together to make a definite rule. Please don't make this new standard work the same way. i.e. don't leave the readers with the idea that "if we didn't mention something, then you can do what you want with it". If something is implementation dependent then the standard should explictly say so. If something isn't defined in the standard then we should assume that this was an omission to be corrected in the future, not a deliberate loophole that every implementor is free to interpret as he wishes. > Seems to me they put more thought > into it than some of their detractors.. True. If I want to make a public fool of myself, that only concerns me. But if the standards are sloppy, then that is everyone's business. This is supposed to be a scientific document giving precise rules; it isn't supposed to be the bible for some religion of C-worshippers who will spend hours pondering its mysteries and trying to interpret its hidden meanings. Just look at the articles that continually appear in this news group. Far too many of them are discussions about what K&R really meant when they said such-and-such, and proofs using quotations from three different sections of the book to show what they really had in mind. Probably at least half of the articles in any year are more or less identical with half the articles in any other year. Wouldn't it be nice to have a document which explicitly tells us how things are supposed to be instead of one which encourages such time-wasting discussions?
mikeb@inset.UUCP (Mike Banahan) (11/28/85)
In article <468@graffiti.UUCP> peter@graffiti.UUCP (Peter da Silva) writes: >The basic complaint is that X3J11 is not a description of 'C', but rather a >description of 'C' under UNIX. There is a good deal of stuff in it that >should not be in the language definition, but rather in a standard >extension: the UNIX compatibility package, for example. I like UNIX, and >I'd like nothing better than to see it become the standard O/S for non >real-time applications (how does one deal with the DST in some little >standalone 'C' program in an RTU in Oman somewhere? They don't even use >it...), but I don't expect it to happen. I like 'C', and I sure hope that >it doesn't become restricted to UNIX and UNIX-like systems. > >That's what I see happening, however, unless X3J11 is (a) ignored or (b) >fixed. And I hope that if they don't (b) fix it, everyone else follows my >example and (a) ignores it. That's not too difficult to get around. What Peter is describing is the `conforming hosted implementation'. He has missed the bit at the front of the draft which says that a `conforming freestanding implementation' doesn't have the libraries: you have to provide your own. It's more painful, but you can write stand-alone code that way. Interestingly, of course the libraries themselves MUST be prepared in a freestanding fashion; it is explicitly forbidden to define a function called `printf' in a hosted implementation! Now some people would come back with the ``read the draft you dummy'' sort of flame - but that isn't why we should be using this newsgroup. However, as one who has played a part in the drafting of the standard, I must admit that it is *EXTREMELY ANNOYING* to see questions posted which are based on the assumption that ``the committee are a bunch of unthinking turkeys''. Postings of that sort are a good way of 1) annoying those who know the answer, enough so they don't reply. and 2) getting the usual raft of know-nothing replies from folk who read an old draft once and now think that they understand it. Believe it or not, most of the committee members know a great deal about C, and care a lot about how the standard ends up. Every single word in that document has been discussed, taken apart, shaken, and put back if it fits. It's worth bearing that in mind if you come across something that doesn't seem to make immediate sense; maybe you're missing the point - there are some subtle problems which take some sorting out. (Sorry Peter - that wasn't aimed at you personally, just a general chide). -- Mike Banahan, Technical Director, The Instruction Set Ltd. mcvax!ukc!inset!mikeb
rbutterworth@watmath.UUCP (Ray Butterworth) (11/28/85)
> > "they took the entry for ctime from the third section of the UNIX > > manual and copied it verbatim" > > Hey, get a current copy of the draft standard! Since April, > the X3J11 spec for ctime has not very much resembled the one > in any UNIX manual. But wasn't compatibility your reason for defending the retention of the use of the pointer? If it doesn't resemble the one in the UNIX manual, does that mean that it is now ctime(time_t) instead of ctime(time_t*)? If not, how do you justify the "*"?
henry@utzoo.UUCP (Henry Spencer) (11/29/85)
> Simply because they have been around for a long time, doesn't > mean that they are the best way of doing things; and simply > because UNIX does it that way, doesn't mean that everyone else > should do it that way. This is supposed to be a C standard, > not a make-the-world-look-like-UNIX standard. This is supposed to be a C standard, not a make-the-world-look-the-way- Ray-wants-it-to standard. That means one uses existing conventions, even if they are a bit silly, rather than gratuitously inventing new ones. People implementing gmtime() have generally followed the Unix conventions. Note that the pointer convention of gmtime() etc. doesn't actually hurt anything; it is silly in a modern context, but that is not sufficient reason to "fix" it and thus break every program that ever used it. > I understand why they originally took pointers; but the need > is no longer there. Now is the time to correct old mistakes > not propagate them. Why, exactly, does this need fixing so badly? > A number of other functions are defined > by the standard that differ from the same functions on UNIX > (at least some versions of UNIX) and people are going to have > to make a number of changes to their code anyway. Name three. If you mean that the standard defines functions which are preferable to the UNIX ones, and that UNIX programs should be redone to use the new ones, that's a different story. My information may be out of date, but I'm not aware of *any* functions in the drafts I've seen that are inconsistent with UNIX usage to the point of breaking code. Not breaking existing legal code was a major objective of the committee! > I know that for anything I write I already have a cover function > for ctime(), so that I can use ctime(time()) without having to > go through the bother of allocating a temporary variable... I trust that you're being informal for the sake of explanation, rather than claiming that you use the name "ctime" for your new function, or that you call time() without a parameter (which is wrong). > One of the biggest problems with the K&R C manual is the things > that it doesn't explicitly mention... Please don't make this new > standard work the same way...If something is implementation dependent then > the standard should explictly say so. This is one of the reasons why writing the X3J11 drafts is much harder work than writing appendix B of K&R -- there really is a major attempt to be precise and complete. But the standard really cannot say "the values of CLK_TIM and BUFSIZ are unrelated even though one happens to be ten times the other" (to pose a silly hypothetical case); it is impractical to disclaim everything, the document becomes unreadable. People using the language must rely on what the standard says and *not* rely on what it doesn't say. The best the standards-writers can do is to make the more obvious and conspicuous non-relationships explicit. Note also that the words "implementation-dependent" in an X3J11 draft have a specific meaning: they mean that the implementor can make the decision as he wishes BUT IT MUST BE DOCUMENTED. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (11/29/85)
> I understand why they originally took pointers; but the need > is no longer there. Now is the time to correct old mistakes > not propagate them. A number of other functions are defined > by the standard that differ from the same functions on UNIX > (at least some versions of UNIX) and people are going to have > to make a number of changes to their code anyway. It wouldn't > be that difficult for the standard to define these functions > with completely different names. I suspect it was much easier to get the committee members to all agree on an acceptable definition that covered the functions already in use than it would be to get them to agree upon totally new interfaces to the time functions. Pointer parameters are not necessarily a "mistake", although they are not the best way to design these functions if one were to do so TODAY. The job of porting applications forward to the new X3J11 environment is much easier if it is compatible with the current (poorly defined) one. The fact of the matter is, most good commercial implementations of non-UNIX C provided UNIX-compatible library routines all along. The most notable exception was Whitesmiths, Ltd., and even then one could get a UNIX-compatible library from Plum Hall, Inc. The X3J11 standard is just defining what an application shall be able to count on in all conforming environments; those of us who have been hauling around our own C libraries will be glad to have them provided for us uniformly across all systems. > There really should be a note here that the meanings of the > values of time_t are implementation defined. Some clarification might indeed be helpful. The meaning of time_t data lies in how they are used, which the library function definitions explain. > One of the biggest problems with the K&R C manual is the things > that it doesn't explicitly mention. It often takes a student > of theological research to find the various hints and put them > together to make a definite rule. Please don't make this new > standard work the same way. i.e. don't leave the readers with > the idea that "if we didn't mention something, then you can do > what you want with it". If something is implementation dependent > then the standard should explictly say so. If something isn't > defined in the standard then we should assume that this was an > omission to be corrected in the future, not a deliberate loophole > that every implementor is free to interpret as he wishes. X3J11 has nicely addressed most of the ambiguities and omissions in K&R. I think it is implicit in any such standard that whatever has not been defined in the standard has no guarantees of any kind. There are uncountably more things not explicitly addressed by the standard than are addressed; it would be infeasible to anticipate them all. If you can identify some specific items that need to be addressed you should bring them to the attention of the X3J11 committee ASAP. I believe the intent is to specify no more and no less than the rules that MUST be followed by a conforming implementation. This implies that anything not specified must NOT be relied on by portable applications code. One need not guess. > This is supposed to be a scientific > document giving precise rules; it isn't supposed to be the bible > for some religion of C-worshippers who will spend hours pondering > its mysteries and trying to interpret its hidden meanings. Agreed, except that "scientific document" is putting it too strongly. The standard represents a consensus of experts, and as such has compromises (like not insisting on the ASCII character set) and weaknesses (like not providing for variable dimensions on formal array parameters). What one hopes is that it will be "good enough" to promote a uniform C environment. My feeling is that it will be. Actually, K&R wasn't too bad, but one had to THINK and UNDERSTAND the ideas and "spirit" of the C language, and a lot of people obviously had trouble in these areas. X3J11 is much more explicit. > Just look at the articles that continually appear in this news group. > Far too many of them are discussions about what K&R really meant > when they said such-and-such, and proofs using quotations from > three different sections of the book to show what they really had > in mind. Probably at least half of the articles in any year are > more or less identical with half the articles in any other year. > Wouldn't it be nice to have a document which explicitly tells us > how things are supposed to be instead of one which encourages such > time-wasting discussions? Exactly. BUT don't expect that to stop idiotic postings to the news group. Many of them in the past could have been resolved by reading VERY CLEAR statements in K&R, but the posters didn't bother to look them up. I think part of the problem is that people are getting incorrect explanations from sources such as amateur hacker journals (and even this newsgroup!), and they don't realize that people propagating bogus information don't know what they're talking about. There is a lot of "unlearning" to be done if one has acquired C "knowledge" from such sources.
gwyn@BRL.ARPA (VLD/VMB) (11/30/85)
There is a BIG difference between "taking the entry for ctime from the UNIX manual and copying it verbatim" and the fact that ctime takes a (time_t *) argument! The former was being accused of X3J11 as an argument that they had not done any thinking about the time functions; that is totally wrong. The latter is the result of the desire not to break a large base of existing code. These are NOT the same issue.
howard@cyb-eng.UUCP (Howard Johnson) (12/04/85)
> As I read it in the Post yesterday, the proposal is to make the polling > places close at 7:00 EST, 8:00 CST, and extend Daylight Savings Time for the > West Coast two more weeks till election day! > > The idea of changing the DST algorithm for a) West Coast sites only, and > b) only in an election year doesn't really turn me on AT ALL... I think this > is a powerful argument for hiding the kluges in either a library routine or > the system. Somewhere it can be setup when the system is configured, and not > have to be replicated in hundreds of programs. If it is in the system, one > would not have to rebuild programs sent from elsewhere, while if it is in the > library one would at least have to re-link-edit. I can just see localtime() scanning a file (perhaps /etc/dst) to figure out whether or not Daylight Savings Time is in effect. This is yet another application crying out for some kind of dynamic link editor. (Hmmm, sounds like this could be cross-posted to net.os...) -- ..!{seismo,topaz,mordor,harvard,gatech,nbires,ihnp4}!ut-sally!cyb-eng!howard (ordered best to worst); also ..!ut-ngp!cyb-eng!howard +1 512 835-2266
peter@baylor.UUCP (Peter da Silva) (01/18/86)
> difftime() accepts time_t arguments but returns a double.
What's wrong with returning a long?
What's wrong with having a function:
long seconds(time)
time_t time;
Really much more generally useful, you know.
But, mainly, returning a double means loading in the floating point package.
On a lot of machines doing any floating point arithmetic in a program adds
quite a bit of overhead. Returning a long would be much more reasonable.
--
-- Peter da Silva
-- UUCP: ...!shell!{baylor,graffiti}!peter; MCI: PDASILVA; CIS: 70216,1076
peter@baylor.UUCP (Peter da Silva) (01/18/86)
> For example (not necessarily optimum), DST could be > indicated by the presence of a specific system file. > The implementation of gmtime() would test for this > (the first time it is called within the process). Boy. You're assuming a lot about a system. Let's say we're doing a IBM-PC implementation. And we want the whole program to fit into a single file because otherwise nobody's going to buy it. And we don't want people to have to create weird files all over the place because then we get really bad reviews. What are we supposed to do? Ask the user for the current time zone every time we run? Create a random file called timezone? Boy, will that help us sell the software. Gee, the user asks, why did I bother buying this real-time-clock card. Basically, X3J11 seems to assume, at a minimum, a minicomputer or supermicro with a hard disk and a guru to create special files all over the place. > I think the concept of DST is stupid, but so long as > it has to be dealt with, some means must be provided. I'm saying that on most small machines it doesn't have to be dealt with, and has no place in a generally useful standard. -- -- Peter da Silva -- UUCP: ...!shell!{baylor,graffiti}!peter; MCI: PDASILVA; CIS: 70216,1076
tj@alliant.UUCP (Tom Jaskiewicz) (01/23/86)
In article <618@baylor.UUCP> peter@baylor.UUCP (Peter da Silva) writes: >> difftime() accepts time_t arguments but returns a double. > >What's wrong with returning a long? 1. time_t may give millisecond resolution (or microseconds (or nanoseconds)) which you really want to have. 2. difftime may need to return a value larger than 2**32 (not likely but possible). In short, you want the range that floating point provides for you. >What's wrong with having a function: > >long seconds(time) >time_t time; Nothing really. But I would rather use difftime *unless* I had a good reason not to, such as running on a machine where >doing any floating point arithmetic in a program adds >quite a bit of overhead. -- #################################################################### # uucp: decvax!linus!alliant!tj ## Bernese are mountains of love. # ####################################################################
msb@lsuc.UUCP (Mark Brader) (01/23/86)
> > difftime() accepts time_t arguments but returns a double. > What's wrong with returning a long? > > What's wrong with having a function: > > long seconds(time) > time_t time; What's wrong is that some non-UNIX systems may wish to keep their internal times based on an origin that is much earlier than UNIX's start-of-1970-GMT. Then a time in seconds-since-origin won't fit in a long. Mark Brader
hand@ncsu.UUCP (Steven Hand) (02/06/86)
By the way, can anyone send me the details on how to order the ANSI C reference manual? Thanks, Steve
karl@haddock (08/13/86)
ANSI C folks, please take note. I've found some questionable things in the May, 1986 draft that I'd like to open up for discussion by the net. (I don't have a more recent copy, or even know if there is one; my apologies if some of these issues have already been closed.) In 3.2.2.3, "(void *)0" is called a null pointer constant, though 5.6.3.12 says the value of NULL is implementation-defined. I take this to mean that the internal representation of (void *)0 need not have all bits clear. The constant 0 used in a pointer context still denotes the null pointer, but an integer variable whose value happens to be zero need not produce the null pointer when cast. Also, if I have a pointer variable whose value happens to be NULL and I cast it into int, I'll likely get the internal form (what I'd get if I used a union) rather than zero as a result, right? In boolean context ("if (p)"), there is an implied comparison with NULL, not an implied cast to int. (In the above, I am assuming sizeof(int) == sizeof(void *).) Do I have this right? In 3.3.3 and 3.3.4, we find the definitions of _u_n_a_r_y_-_e_x_p_r_e_s_s_i_o_n and _c_a_s_t_-\ _e_x_p_r_e_s_s_i_o_n. Wouldn't it have been simpler to define cast to be a unary operator? (That's the way *I* always think of it.) In other words, it seems one could add "( _t_y_p_e_-_n_a_m_e ) _u_n_a_r_y_-_e_x_p_r_e_s_s_i_o_n" to the 3.3.3 syntax and move section 3.3.4 to 3.3.3.x. Am I overlooking something? In 4.2.1.1: "If NDEBUG is defined ... use of the assert macro will have no effect." This needs to be clarified as follows: "The expression {shall|may| shall not} be evaluated for side effects." (Consider e.g. "assert(getchar()\ ==EOF)", for example.) The UNIX* version currently does not evaluate it; it sometimes would be more useful if it did. In any case the ambiguity needs to be resolved. In 4.7.1.1, we see that all signals are initialized to SIG_DFL, a surprising contrast to the way things currently work on UNIX, where signals can be set to ignore (by nohup(1) or other means) before the program starts. I see two interpretations: [a] SIG_DFL means "die on this signal"; programs like nohup can no longer be written. [b] If nohup presets the signal to be ignored, then for the duration of the program exec'd from it, SIG_DFL means "ignore this signal". The first interpretation is clearly a problem. The second is more subtle. I think "if (signal(SIGINT, SIG_IGN) == SIG_IGN) signal(SIGINT, trap);" would now be broken, because the first signal() will return SIG_DFL rather than SIG_IGN. In 4.9.3: "When opened, the standard streams are fully buffered if and only if the stream does not refer to an interactive device." So, stderr isn't a special case anymore? (It's currently unbuffered.) In 4.9.6.1 and 4.9.6.2 (fprintf and fscanf), it says that any conversion specifier other than those listed results in undefined behavior if it's a lower-case letter, otherwise implementation-defined behavior. In other words, the lower-case letters are reserved for future official releases, and the other characters are reserved to the implementation. This is a bad idea. Note that the flag characters occupy the same "namespace" as the conversion specifiers; future non-alphabetic flags could potentially clash with some implementation's conversion specifier. I suggest that there should be *one* character reserved for the implementation, which can be used as a prefix. E.g. if I want my library to have a binary-output format, I could then use "%&b" if "&" is the prefix. Sort of like a run-time #pragma. In 4.9.6.2, the documentation for the "[" conversion specifier (which scans a string not delimited by white space) fails to mention a range syntax, but the example on the next page uses "%[0-9]". Also, it fails to mention whether one can include a right-bracket in the scanset; most implementations allow it as the first character (following the "^", if any). (Unless they want to allow an empty scanset, in which case *that* should be documented.) In 4.10.4.4, we see that any function (presumably the user's) which is registered by onexit() should take zero arguments and return a value of type onexit_t. No mention is made of what this return value should be, or who will look at it. The function onexit() itself returns type onexit_t, but the only comment is that it "compares equal to a null pointer constant" if it succeeds. (Aha, so onexit_t must be some kind of pointer!) If the user is only expected to test for success/failure, why not just return an int? It seems to me that this could have been declared "int onexit(void (*)(void))", omitting the onexit_t stuff completely. But, back in 4.10 it was claimed that onexit_t "is the type of both the argument to and the value returned by the onexit function". One wonders if "argument to [onexit]" should have been "result of the function pointed to by the argument to [onexit]". If not, and we take it literally, we conclude that "onexit_t" is a synonym for "onexit_t (*)(void)", an undeclarable type. Someone hinted at this some months ago in an earlier posting, so maybe it's true. But why? Finally, in 5.1.3 we have a really serious error :-). "#error" and "#pragma" are listed in the wrong font. Karl W. Z. Heuer (ihnp4!ima!haddock!karl), The Walking Lint *UNIX is a trademark of AT&T Bell Laboratories.
guy@sun.uucp (Guy Harris) (08/14/86)
> In 3.2.2.3, "(void *)0" is called a null pointer constant, though 5.6.3.12 > says the value of NULL is implementation-defined. I take this to mean that > the internal representation of (void *)0 need not have all bits clear. Yes. I'm certain there are many machines out there that either have C implementations or should have them that have a representation for null pointers that is not a bucket of zero bits. > The constant 0 used in a pointer context still denotes the null pointer, > but an integer variable whose value happens to be zero need not produce > the null pointer when cast. Yes. This may be considered questionable, since, given the declarations int i; char *p; the statements i = 1; p = i; and p = 1; should be expected to stuff the same value into "p", but the statements i = 0; p = i; and p = 0; need not stuff the same value into "p" - i.e., the constant expression 0 is treated differently when converting to a pointer type than any other integral expression. Unfortunately, there's not a hell of a lot you can do about it. If C had a keyword "nil" that would, when it appears in an expression, be converted to a null pointer of the appropriate type (as the constant expression 0 is converted now), this problem wouldn't occur; however, it's a little to late to fix this now, given all the code out there that uses 0 for this. "Fixing" it the other way, by having any integral expression with the value 0 convert to a null pointer, would 1) add some extra inefficiency to integer-to-pointer conversions on machines with special null pointer representations without much benefit (if any), and 2) surprise some code that does want to grab a pointer value, fiddle the bits (setting a ring number, for instance) and then stuff the value back into the pointer, if a pointer value of all zero bits is a valid pointer. > Also, if I have a pointer variable whose value happens to be NULL and I > cast it into int, I'll likely get the internal form (what I'd get if I > used a union) rather than zero as a result, right? Right. > In boolean context ("if (p)"), there is an implied comparison with NULL, > not an implied cast to int. Actually, it's an implied comparison with 0; however, the 0 has to get converted to the type of "p", so that the effect is the same as "if (p == 0)", namely that "p" gets compared with a null pointer. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)
msb@dciem.UUCP (Mark Brader) (08/15/86)
Somebody writes: > > In 3.2.2.3, "(void *)0" is called a null pointer constant, though 5.6.3.12 > > says the value of NULL is implementation-defined. I take this to mean that > > the internal representation of (void *)0 need not have all bits clear. Guy Harris (guy@sun.uucp) replies: > Yes. I'm certain there are many machines out there that either have C > implementations or should have them that have a representation for null > pointers that is not a bucket of zero bits. This is almost correct. It IS true that (void *)0 need not have all bits clear, but this is not what the reference in 5.6.3.12 is saying. What it is saying is that your implementation can #define NULL as either 0 or (void *)0. Mark Brader, dciem!msb #define MSB(type) (~(((unsigned type)-1)>>1))
karl@haddock (08/16/86)
haddock!karl (Karl Heuer) writes: >> The constant 0 used in a pointer context still denotes the null pointer, >> but an integer variable whose value happens to be zero need not produce >> the null pointer when cast. sun!guy (Guy Harris) replies: >Yes. This may be considered questionable, since, given the declarations >"int i; char *p;" the statements "i=1; p=i;" and "p=1;" should be expected >to stuff the same value into "p", but the statements "i=0; p=i"; and "p=0;" >need not stuff the same value into "p" - i.e., the constant expression 0 is >treated differently when converting to a pointer type than any other >integral expression. In particular, "p = i = 0;" is a loser! (I don't expect many programs do this, since it produces a pointer/integer conflict.) >Unfortunately, there's not a hell of a lot you can do about it. If C had a >keyword "nil" that would, when it appears in an expression, be converted to >a null pointer of the appropriate type (as the constant expression 0 is >converted now), this problem wouldn't occur; however, it's a little to late >to fix this now, given all the code out there that uses 0 for this. It's not too late. In the first place, NULL already exists for this purpose (though some people insist on using it as a synonym for '\0' too!) If zero- in-pointer-context henceforth produces a warning message, people will convert their programs to use NULL instead. If the feature then goes away, only the programmers who ignored the warning will be burned. (This is not necessarily a good idea, but it *can* be done.) NULL would presumably be changed from "0" to an implementation-defined constant like "(void *)0xF0000000". >"Fixing" it the other way, by having any integral expression with the value >0 convert to a null pointer, would ... surprise some code that does want to >grab a pointer value [as int] and then stuff the value back into the >pointer, if a pointer value of all zero bits is a valid pointer. Hmm, there's a similar problem without the full-check conversion. If the constant zero is converted into a null pointer constant, and zero is a valid address, and something of interest is at that absolute address, how do I reference it? "x = *(int *)0" will try to dereference NULL instead of 0, and "i = 0; x = *(int *)i" will undoubtable fail on some optimizing compilers. Karl W. Z. Heuer (ihnp4!ima!haddock!karl), The Walking Lint
guy@sun.uucp (Guy Harris) (08/16/86)
> It's not too late. In the first place, NULL already exists for this purpose > (though some people insist on using it as a synonym for '\0' too!) If zero- > in-pointer-context henceforth produces a warning message, people will > convert their programs to use NULL instead. Yes, but I don't know whether the disruption that would cause at this late date would be worth the advantages the changes you suggest would bring. 1) I've seen a fair amount of code that does things like <something> *p; ... if (p == 0) (which is perfectly legitimate and type-correct C) and makes calls like execl("/bin/cat", "cat", "file", (char *)0); 2) What happens to code like <something> *p; ... if (p) or if (!p) which is also, at least by my interpretation of the August 11, 1985 ANSI C draft, perfectly legitimate and type-correct C. The discussions of Boolean objects (now that Root Boy is gone, I guess we can acknowledge the existence of Boolean objects in C again) in the draft talk use terms like "equals 0" or "does not equal 0"; I presume some expression X "equals 0" iff X == 0, and "does not equal 0" iff X != 0. Both of those comparisons can be done on pointers. The code in both these examples will have to be changed. The ANSI C committee is at least trying not to break existing code any more than is absolutely necessary. > NULL would presumably be changed from "0" to an implementation-defined > constant like "(void *)0xF0000000". Blech! I suppose the compiler will recognize expressions like that and, if it treats null pointers in any special way, will treat them as such, but it seems ugly. (Yes, a compiler *could* treat them in usefully special ways. For instance, it might try to do dataflow analysis and figure out whether you run the risk of dereferencing a NULL pointer or not. Said dataflow analysis would have to be interprocedural, of course, and cross module boundaries; however, given the depressing amount of crap code out there that is careless about null pointers, it might be worth it.) > Hmm, there's a similar problem without the full-check conversion. If the > constant zero is converted into a null pointer constant, and zero is a valid > address, and something of interest is at that absolute address, how do I > reference it? "x = *(int *)0" will try to dereference NULL instead of 0, > and "i = 0; x = *(int *)i" will undoubtable fail on some optimizing > compilers. Why? If the compiler implements C, it will NOT combine the two statements into one, since the meaning of "x = *(int *)0" is undefined, but the meaning of "x = *(int *)i" is defined to the extent that conversions of "int" to "int *" is defined. The optimizer might decide that the value of "i" is known at that point, and compute the value of "(int *)0" at compile time, and generate code to load the "int" value that would be located at that address into "x". It might then discover that "i" is dead at that point, and throw it away. No C compiler will generate code to dereference a null pointer for that example; any compiler that does is compiling a language other than C. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)
faustus@ucbcad.BERKELEY.EDU (Wayne A. Christopher) (08/18/86)
If there is a compiler that defines NULL as something other than an all-0 bit pattern, I certainly hope that "if (!p)" will do the right thing, otherwise most existing code won't work. But this should never be a real problem, since all the loader has to do is guarantee that nothing valid will ever have an address that corresponds to the conversion of integer 0 to a pointer. There are no architectural considerations involved -- if there are tag bits, etc, just let them be all 0 -- the pointer should never be referenced anyway, so who cares what the tag bits are. In article <86900017@haddock>, karl@haddock writes: > > "Fixing" it the other way, by having any integral expression with the value > > 0 convert to a null pointer, would ... surprise some code that does want to > > grab a pointer value [as int] and then stuff the value back into the > > pointer, if a pointer value of all zero bits is a valid pointer. You can always use a union, or cast a pointer to the needed value -- these tricks are used for things like dissecting floating point numbers. > Hmm, there's a similar problem without the full-check conversion. If the > constant zero is converted into a null pointer constant, and zero is a valid > address, and something of interest is at that absolute address, how do I > reference it? If there is something of interest at location 0 then you should complain to whomever put it there. It's a very good idea to make null pointer references cause a fault -- this catches lots of nasty bugs. If this isn't the case on your machine, you can still use the tricks mentioned above. Wayne
ron@brl-sem.ARPA (Ron Natalie <ron>) (08/21/86)
In article <971@ucbcad.BERKELEY.EDU>, faustus@ucbcad.BERKELEY.EDU (Wayne A. Christopher) writes: > If there is something of interest at location 0 then you should complain to > whomever put it there. It's a very good idea to make null pointer references > cause a fault -- this catches lots of nasty bugs. If this isn't the case > on your machine, you can still use the tricks mentioned above. > Even the PDP-11's used to put a zero on the split-I/D images at zero to assure there wasn't anything useful at zero. Unfortunately, people learned to rely on this. I suspect we might not have had as much problems if VAX's and PDP-11's had something useless like at "setd" instruction at the bottom of their dataspaces -Ron (p&P6) Natalie
bzs@bu-cs.BU.EDU (Barry Shein) (08/22/86)
An amusing anecdote on NULL pointers: On our large IBM system an early version of one of the screen editors had a null pointer problem. Basically, it would load the contents of address 0 into a register rather than a zero. Of course, the contents of location zero was zero. Usually. Address zero on an IBM is the Machine Check PSW double-word. This will contain the PSW if a machine check recently occurred (PSW is the combined processor status, program counter, machine check means a detected hardware error, obviously not fatal or why put it there.) You guessed it! Mysterious failures of the editor as address 0 contained non-zero values for fleeting microseconds after a machine check, which was a rare event. I guess the area got re-zeroed after the O/S logged the error (or whatever.) It handled the machine check asynchronously (maybe this was really caused by the dual processors, I don't remember.) Fun fun. Kids, our lives were already ruined by this sort of self-abuse, but you're young, you can be saved, ah youth, wasted on the young :-) -Barry Shein, Boston University