brandenberg@star.dec.com.UUCP (01/26/87)
[ From sun!gorodish!guy ] > From [?] >>God forbid, but there is probably some C program out there that relies >>on being able to: >> int a,b, *ptr; >> >> ptr = &a; >> ptr++; >> /* ptr now points to b */ > >No program that relies on that is correct C, so no compiler is >obliged to make them work. In fact, the sooner such programs *are* >prevented, the better off we'll all be. Oh? If this is aberrant coding, you might want to look at your varargs.h file whose operation relies on these assumptions; and this is in the ANSI proposal. - Monty ------------- Industry Standards: Advancing computer engineering to the lowest common denominator.
dce@mips.UUCP (01/26/87)
In article <7803@decwrl.DEC.COM> brandenberg@star.dec.com (bleakness...desolation...plastic forks...) writes: > >[ From sun!gorodish!guy ] ... >>No program that relies on that [aliasing] is correct C, so no compiler is >>obliged to make them work. In fact, the sooner such programs *are* >>prevented, the better off we'll all be. > >Oh? If this is aberrant coding, you might want to look at your >varargs.h file whose operation relies on these assumptions; and this is >in the ANSI proposal. > > - Monty Hold on. What Guy says is that no compiler is "obliged" to make the specifically given code work. The ANSI proposal requires that varargs.h be implemented and that it aid in performing a certain function. It does not say *how* variable number of arguments has to work. In the Mips system, where the first 4 parameters to a subroutine are passed in registers, the compiler actually keys on the word 'va_alist' in the argument list to force the parameters to be copied onto the stack. Because of this, you can actually do some very machine-dependent code. For example, I've found cases where code like: error(code, fmt, args) int code; char *fmt; int args; { ... _doprnt(fmt, &args, stderr); ... } was "ported" to our system by simply changing all instances of "args" to "va_alist". This was done because the person doing the porting looked at varargs.h and used system-dependent knowledge instead of using what the definition says. The fact that "it works" doesn't make it legal, since it doesn't use the "required" va_start() or va_end(). Basically, all the ANSI proposal says is that a conforming system has to supply: a. varargs.h, which may even be effectively empty b. the items listed in varargs(3) It makes no difference to the ANSI proposal whether va_alist is a macro, a typedef, or a builtin type. It shouldn't matter to the code how the arguments are stored or how va_arg() is implemented. Don't confuse requirements for functionality with requirements for architectural conformity. -- David Elliott UUCP: {decvax,ucbvax,ihnp4}!decwrl!mips!dce, DDD: 408-720-1700
guy@gorodish.UUCP (01/26/87)
>Oh? If this is aberrant coding, you might want to look at your >varargs.h file whose operation relies on these assumptions; and this is >in the ANSI proposal. Sorry, but this just doesn't hold water. The ONLY thing in the ANSI proposal about "varargs" is that there is an include file <stdarg.h> (NOT <varargs.h>!) and that when you include it certain things are defined. There is nothing whatsoever in the ANSI spec that requires that the <varargs.h> distributed with most UNIX systems has to work; in fact, there are implementations on which it DOESN'T work. (Consider a machine with register windows, where the first N scalar parameters are not placed in memory at all - or any other implementation that passes parameters in registers.) Those implementations have to do something else to make it work. There is nothing in the ANSI draft that says anything whatsoever about where variables are placed in memory relative to one another - or about whether variables whose address isn't taken need be in memory at all!
radford@calgary.UUCP (01/27/87)
In article <7803@decwrl.DEC.COM>, brandenberg@star.dec.com (bleakness...desolation...plastic forks...) writes: > >> int a,b, *ptr; > >> > >> ptr = &a; > >> ptr++; > >> /* ptr now points to b */ > > > >No program that relies on that is correct C... > > Oh? If this is aberrant coding, you might want to look at your > varargs.h file whose operation relies on these assumptions; and this is > in the ANSI proposal. As I understand it, the ANSI proposal specifies that the FUNCTION of varargs.h must exist, not that the particular varargs.h source file you are looking at must work. Indeed, there would be no point in mentioning varargs.h in the standard if the code it contained was guaranteed to work on all machines. Radford Neal
cdshaw@alberta.UUCP (01/28/87)
This argument about pointer games should really be in comp.lang.c (or something). Anyway, it's getting very stale here in comp.arch. -- Chris Shaw cdshaw@alberta University of Alberta CatchPhrase: Bogus as HELL !
chris@mimsy.UUCP (Chris Torek) (01/28/87)
Guy hardly needs defending, but it may sound better coming from two people: /* this code is not portable */ int a,b, *ptr; ptr = &a; ptr++; /* ptr now points to b */ >[ From sun!gorodish!guy ] >>No program that relies on that is correct C, so no compiler is >>obliged to make them work. In article <7803@decwrl.DEC.COM> brandenberg@star.dec.com (bleakness...desolation...plastic forks...) writes: >Oh? If this is aberrant coding, you might want to look at your >varargs.h file whose operation relies on these assumptions; and this is >in the ANSI proposal. Wrong. *Varargs* is in the ANSI proposal. Neither the *Vax* *implementation* nor the *Sun* *implementation* (each of which works by peeking at stack addresses) is the ANSI proposal. Nor is Pyramid's implementation, which is considerably more complex and does *not* rely upon `ptr = &a; ptr++;' pointing to `b' (which is only sometimes the case). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu
jpn@teddy.UUCP (01/29/87)
>Oh? If this is aberrant coding, you might want to look at your >varargs.h file whose operation relies on these assumptions; and this is >in the ANSI proposal. Sigh.... Varargs is DEFINED as being machine-dependent - in other words, those varargs macros/functions may have to be rewritten for every machine - it is up to the system providers to provide definitions that work for a SINGLE machine: the one that is being compiled for. Any user code that does this is not portable. >>> int a,b, *ptr; >>> >>> ptr = &a; >>> ptr++; >>> /* ptr now points to b */ Any program that is expected to work on more than one machine MUST NOT make assumptions about memory layout. This is the reason why varargs exists: So that 100's of programs do not have to make such assumptions! Sure, this is legal C, but the trailing comment is NOT NECESSARILY TRUE!
guy@gorodish.UUCP (02/02/87)
>Nor is Pyramid's implementation, which is considerably more complex and >does *not* rely upon `ptr = &a; ptr++;' pointing to `b' (which is >only sometimes the case). I presume this is because it's a register-window machine, and some parameters may be passed in registers, so that not all of the parameters are necessarily stored in memory? This is one reason *why* the ANSI proposal can't just say "the 'conventional' implementation of 'varargs' has to work." There may be machines where you can't make it work!
hansen@mips.UUCP (02/03/87)
In article <12570@sun.uucp>, guy%gorodish@Sun.COM (Guy Harris) writes: > >Nor is Pyramid's implementation, which is considerably more complex and > >does *not* rely upon `ptr = &a; ptr++;' pointing to `b' (which is > >only sometimes the case). > > I presume this is because it's a register-window machine, and some > parameters may be passed in registers, so that not all of the > parameters are necessarily stored in memory? The MIPS compiler, which passes four arguments in registers, will recognise the use of the <varargs.h> constructs in the argument list and push the registers back out to memory when required. This permits printf-line routines to work, which is a more severe constraint than <varargs.h> itself, as the argument list is normally passed onto routines such as _doprnt by the address of the format string argument. It certainly makes porting code easier than rewriting everything to use the formal varargs interface as strictly defined, and for that I'm already grateful to our compiler team. -- Craig Hansen | "Evahthun' tastes MIPS Computer Systems | bettah when it ...decwrl!mips!hansen | sits on a RISC"
csg@pyramid.UUCP (02/03/87)
>>Nor is Pyramid's implementation, which is considerably more complex and >>does *not* rely upon `ptr = &a; ptr++;' pointing to `b' (which is >>only sometimes the case). > >I presume this is because it's a register-window machine, and some >parameters may be passed in registers, so that not all of the >parameters are necessarily stored in memory? Exactly. The first 12 scalar arguments are passed through the register window, from left to right in registers pr0, pr1, pr2, etc. Structures (including one- word structs) and args beyond the 12th are pushed on the stack in order from right to left (VAX style). Doubles need two registers and are always aligned on an 8-byte boundary (to prevent an argument from straddling the register file and the stack). Since you can take the address of a register on the Pyramid, it is possible to do a VAX style varargs so long as you don't try to pass structs or doubles, or use more than 12 arguments. Like Chris said, "only sometimes the case." If you try taking the address of local variables, which is where this silly discussion started, you are totally hosed. The order of assignment in the register file is picked by the compiler, based on the frequency of reference. And if you declare "int a, b" and the references to them are isolated from each other, they will likely end up being the same register. <csg>
ramin@scampi.UUCP (02/06/87)
In article <5230@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > Guy hardly needs defending, but it may sound better coming from two > people: > > /* this code is not portable */ > int a,b, *ptr; > > ptr = &a; > ptr++; > /* ptr now points to b */ > I agree entirely... In fact, I conducted a quick experiment on a Sun-3 system which resulted in vastly different results depending on the location of the "int a,b, *ptr" line: long a,b,*ptr; /* note: it's static */ main() { a = 1; b = 2; ptr = &a; ptr++; *ptr = 3; printf("%08.8X %08.8X %08.8X\n",&a,&b,ptr); printf("%d %d %d\n",a,b,*ptr); } which resulted in: 00020DBC 00020DC0 00020DC0 1 3 3 and also... main() { long a,b,*ptr; /* note: it's NOT static */ a = 1; b = 2; ptr = &a; ptr++; *ptr = 3; printf("%08.8X %08.8X %08.8X\n",&a,&b,ptr); printf("%d %d %d\n",a,b,*ptr); } which gave: 0EFFFE98 0EFFFE94 0EFFFE9C 1 2 3 Now obviously the second program is a *VERY* problematic one considering the compiler put a and b on the stack in the reverse order. As far as I'm concerned both are severely brain-damaged ways of coding. But the original topic was slanted towards varargs (i.e. AFTER having called something and the gripe against making assumptions about doing the above to a call frame) and it got somewhat sidetracked to discussions of proper C-coding. A utility supplied with a compiler should be able to to make certain assumption about how the compiler and the machine it is targeted at pass parameters back and forth. For the mortals using the compiler to make such an assumption and maintain portability is folly... ramin -- (insert-file ".disclaimers") ramin firoozye' {ihnp4,lll-lcc,hoptoad}!scampi!ramin systems control inc. (415) 494-1165 x-1777 1801 page mill road palo alto, ca 94304 *** Wars are not fought to decide who is right... Only who is left... ***
wcs@ho95e.UUCP (02/08/87)
[line-eater bait, included because] [2.11news wants some extra lines anyway] In article <5230@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: >> Guy hardly needs defending, but it may sound better coming from two >> people: >> /* this code is not portable */ >> int a,b, *ptr; >> ptr = &a; >> ptr++; >> /* ptr now points to b */ This code works especially well if your optimizing compiler puts b in a register. Even the proverbial lament "but it worked on my *VAX*" may not apply here. -- # Bill Stewart, AT&T Bell Labs 2G-202, Holmdel NJ 1-201-949-0705 ihnp4!ho95c!wcs