From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,ac02560f0af03a21 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2004-01-06 22:37:39 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!news-out.visi.com!petbe.visi.com!ash.uu.net!wn14feed!worldnet.att.net!bgtnsc05-news.ops.worldnet.att.net.POSTED!not-for-mail From: Dave Thompson Newsgroups: comp.lang.ada Subject: Re: GNAT parameter passing, C-style? Message-ID: References: <1072458199.346049@master.nyc.kbcfp.com> <3fec7c21$0$4764$61fed72c@news.rcn.com> <4iBIb.8173$qS3.498@nwrdny03.gnilink.net> <1072883131.278899@master.nyc.kbcfp.com> X-Newsreader: Forte Agent 1.93/32.576 English (American) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Wed, 07 Jan 2004 06:37:39 GMT NNTP-Posting-Host: 12.76.19.89 X-Complaints-To: abuse@worldnet.att.net X-Trace: bgtnsc05-news.ops.worldnet.att.net 1073457459 12.76.19.89 (Wed, 07 Jan 2004 06:37:39 GMT) NNTP-Posting-Date: Wed, 07 Jan 2004 06:37:39 GMT Organization: AT&T Worldnet Xref: archiver1.google.com comp.lang.ada:4164 Date: 2004-01-07T06:37:39+00:00 List-Id: On Wed, 31 Dec 2003 16:30:17 GMT, "Frank J. Lhota" wrote: > "Hyman Rosen" wrote in message > news:1072883131.278899@master.nyc.kbcfp.com... > > Frank J. Lhota wrote: > > The upshot is that even when calling a function without a prototype, the > > compiler may pass arguments any way it likes, and it is absolutely not > > required to "push" them onto a "stack" in any particular order. > > It may not be required by the standard, but it is required to support legacy > code. Certainly any C code written after ANSI C became widely available > should use prototypes, but for many years there was plenty of maintained K&R > C code written like this: > > extern int futz(); > { > ... > if ( futz( name, count ) ) ... > } > (Well, not exactly like that, the call needs to be within a body. Unless you're putting the declaration and the (redundantly) compound statement both within a body, which is rarely done or useful.) > where there is no indication as to whether or not the function takes a > variable argument list. You can argue all you want that a compiler is not > required to generate correct code for such a program, but the sheer weight > of legacy code forces the compiler manufactures to not break code like this. > It did for a while and to an extent, but that was over a decade ago. Anyone who has code today that uses varargs and doesn't properly declare them (with prototypes) is in pretty bad shape. > I go back to my original question: does anyone know of a C compiler which, > when compiling C (not C++) does not default to the C calling convention > (i.e. arguments pushed on the stack in reverse order, and popped off by > calling function) in the absence of any indication of another convention? > The two C compilers I am currently using (GCC version 3.3.1, MSVC Version 6) > both default to the C convention. I recall that every Borland compiler up to > 4.0 defaulted to the C convention as well, as did the early Zortech / > Symantec compilers. > Aha -- as developed downthread, if you limit yourself to x86, especially when you trace back to 286 or earlier, with their limited registers and hardware downward stack (used by call and ret), there is an obvious convention that everyone uses, even though/if not formally mandated. This is not true across all (other) architectures, and it is precisely because pre-Standard non-flagged varargs was a nonportable and unreliable hack that the Standard changed it. F.ex. my hobbyhorse the "classic" Tandem (later Compaq and HP) NonStop CPUs had/have? in "hardware" an *upward* stack, and a convention used by all (other) languages and the OS that arguments are pushed (upward) left to right and accessed by callee at fixed small negative offsets from the framepointer, for which a special addressing mode exists. C on this architecture conforms to this convention for non-vararg routines to allow interop especially with the OS; but this doesn't work for vararg because the fixed arguments (and vararg-start) would not be at known/fixed offsets, so vararg pushes (upward) right to left and are accessed going downwards. As an obvious result, calls that should be vararg and aren't or vice versa fail horribly. The last ~2.5 generations of Tandem systems, called TNS/R to distinguish, actually use (MIPS) RISC CPUs with the more common downward stacks, but still run TNS code in emulation; and since Tandem systems were (sold and) bought mostly for mission-critical applications in large conservative businesses I'd estimate a fair chunk of running code is emulated TNS. > Again, I am not saying this out of fondness for the C calling convention. > The original K&R specification, unfortunately, forced the undesirable use of > this convention for many years. The C++ people should be congraduated for > making a bold enough break from the past to eliminate almost all need for > this convention. > The original K&R left it out, basically leaving *printf, *scanf, and such as implementation magic. It didn't *require* it be done badly, but didn't help at all in doing it well either. > I should also note that this has never been an issue in Ada. (This is an Ada > newsgroup, after all). > - David.Thompson1 at worldnet.att.net