tom@vrdxhq.UUCP (04/28/87)
This may be a dumb question, but could someone please explain to me how I assign an absolute address to a pointer to an array? I'm trying to overlay various structures and arrays at different times on top of the physical page frame in EMM. I'm using MSC 4.0 I want to do the following : int *aa[]; aa = 0x50000; -- or even better -- struct POINTER_PARTS { unsigned offset_part; unsigned segment_part; } union POINTER_ACCESS { struct POINTER_PARTS pp; int *far_pointer; } union POINTER_ACCESS upa; upa.pp.segment_part = 0x5000; upa.pp.offset_part = 0x0; aa = upa.far_pointer; === I keep getting "need lvalue" type errors. Any help anyone can provide, or comments on my code example, are greatly appreciated.
toma@tekgvs.TEK.COM (Thomas Almy) (04/29/87)
In article <3537@vrdxhq.UUCP> tekgvs!tekcrl!tektronix!uw-beaver!teknowledge-vaxc!sri-unix!husc6!seismo!vrdxhq!tom tom@vrdxhq.UUCP (Tom Welsh) writes: > >This may be a dumb question, but could someone please explain >to me how I assign an absolute address to a pointer to an array? >... >I'm using MSC 4.0 > I thought that this would be general enough to followup rather than reply. You have to remember that addresses of "far" data structures are longs and not ints. For SMALL or MEDIUM memory models (i.e., one data segment), you can say int far *aa[]; /* aa is a far pointer to an array of ints */ aa = (int far *) 0x50000L; /* for a fixed address */ #define absAddress(segment,offseg) (((long)(segment) << 16) + (offseg)) aa = (int far *) absAddress(5,0); /* for convenience */ For COMPACT or LARGE memory models (i.e., more than one data segment), just delete the keyword "far" from the preceeding examples. Tom Almy (I hate C, but use it twice a day)
chris@mimsy.UUCP (Chris Torek) (04/29/87)
In article <3537@vrdxhq.UUCP> tom@vrdxhq.UUCP (Tom Welsh) writes: >This may be a dumb question, No, pointers and arrays and their interconversions are a common confusion point in C. >but could someone please explain to me how I assign an absolute >address to a pointer to an array? Given your example, you should use a pointer, not a pointer to an array. The C language assumes a flat memory space*, and given this assumption, a single pointer can tell you everything you need to know about a one-dimensional array save its size (which C does not use anyway, in this case). (*The flat space is only per data object, which allows segmented implementations on the 80x86.) >int *aa[]; % cdecl explain int *aa[] declare aa as array of pointer to int % In other words, this is an array of unspecified size (which is treated as though it were an `extern' definition, and allocates no memory, but, at least on Unix compilers, does set the symbol), each member of which points to zero or more integers. >-- or even better -- >struct POINTER_PARTS > { > unsigned offset_part; > unsigned segment_part; > } >union POINTER_ACCESS > { > struct POINTER_PARTS pp; > int *far_pointer; > } >union POINTER_ACCESS upa; >upa.pp.segment_part = 0x5000; >upa.pp.offset_part = 0x0; >aa = upa.far_pointer; This is indeed better: Simply leave out the final assignment, and use <int_lvalue> = upa.far_pointer[<int_expr>]; If you need a separate variable: int *aa; union POINTER_ACCESS upa; ... set upa ... aa = upa.far_pointer; `int *aa' is a pointer to a block of memory just as much as it is a pointer to a single `int'. The only thing that distinguishes the two is the programmer. (Yes, one can argue for `int (*aa)[]', but the current dpANS does not allow this declaration---though it does allow `int ar[]; &ar', in which &ar has type int (*)[]!) -- 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
mason@gargoyle.UChicago.EDU (Tony Mason) (04/30/87)
>>This may be a dumb question, but could someone please explain >>to me how I assign an absolute address to a pointer to an array? >>... >>I'm using MSC 4.0 >> >You have to remember that addresses of "far" data structures are longs and >not ints. > >For SMALL or MEDIUM memory models (i.e., one data segment), you can say > >int far *aa[]; /* aa is a far pointer to an array of ints */ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unless my understanding of C (and of those around me) has just gone out the window, that is an array of far pointers to integers. To make the delcaration fit the comment it should be: int far *aa; /* aa is a far pointer to an array of ints */ Now you just use integer arithmetic to acces elements in the array (eg. *(aa + 4) would be the fifth integer in the array). To make the comment match the declaration : int far *aa[]; /* aa is an array of far pointers to integers */ Now, to access an integer, you would use something like *aa[4] to access the integer pointed at by the fifth element of the pointer array. Finally, if you use the undefined array size syntax, you are defining something that must be external (or in a function declaration list). Whether or not the compiler should accept this at all is quite suspect (at least to me) without an extern in front. As for using far, that is only necessary when you are using (1) any model with restricted data size AND (2) accessing a data structure outside the normal data segment. In line with the type of question asked, this is probably NOT what was being asked. I think the confusion in this case was with pointer declarations, not access problems. Tony Mason Univ. of Chicago, Dept. of C.S. ARPA: mason@gargoyle.uchicago.edu UUCP: ...ihnp4!gargoyle!mason
rh@cs.paisley.ac.uk (Robert Hamilton) (05/01/87)
In article <3537@vrdxhq.UUCP> tom@vrdxhq.UUCP (Tom Welsh) writes: > >This may be a dumb question, but could someone please explain >to me how I assign an absolute address to a pointer to an array? > >I'm trying to overlay various structures and arrays at different >times on top of the physical page frame in EMM. > >I'm using MSC 4.0 > >I want to do the following : > > >int *aa[]; > > >aa = 0x50000; This is an old one. int *aa[] is actually a *constant* So you cant assign to it. Try int **aa; aa= (int **) 0x50000; This should be ok. Subtle difference between *aa[] and **aa !! -- JANET: rh@uk.ac.paisley.cs EMAIL: rh@cs.paisley.ac.uk | Post: Systems manager. UUCP: ...!seismo!mcvax!ukc!paisley!rh | Department of Computing, Phone: +44 41 887 1241 Ext. 219 | Paisley College | High St. Paisley. | Scotland. | PA1 2BE
jfh@killer.UUCP (John Haugh) (05/06/87)
In article <3537@vrdxhq.UUCP>, tom@vrdxhq.UUCP (Tom Welsh) writes: > > This may be a dumb question, but could someone please explain > to me how I assign an absolute address to a pointer to an array? > > I'm trying to overlay various structures and arrays at different > times on top of the physical page frame in EMM. > > I'm using MSC 4.0 > > I want to do the following : > > > int *aa[]; This is not a pointer to an array. This is an array of pointers. So, the assignment > aa = 0x50000; doesn't make much sense. If you want a pointer to an array, you could try int **aa; which works nicely, since the [] is really not all that needed (flame retardant statement). If you REALLY want a pointer to an array, how about int *(aa[]); The parenthesis come in real handy at times, for example (small lesson in C to follow :-) when you can't figure out how to declare a 'something' with a weird shape. My weakness is pointers to functions - int foo (); /* this is a function */ int *foo (); /* this is a function RETURNING a pointer */ int *(foo ()); /* pointer to first function */ I won't even bother with POINTER to FUNCTION returning POINTER to FUNCTION returning an integer (the return value of signal() is one of these). - John. Disclaimer: I don't have the slightest idea what I am talking about. I can't handle these problems either.
chris@mimsy.UUCP (Chris Torek) (05/10/87)
In article <857@killer.UUCP> jfh@killer.UUCP (John Haugh) writes: >The parenthesis come in real handy at times, for example (small lesson in >C to follow :-) when you can't figure out how to declare a 'something' with >a weird shape. My weakness is pointers to functions - > int foo (); /* this is a function */ Right; > int *foo (); /* this is a function RETURNING a pointer */ right; and > int *(foo ()); /* pointer to first function */ wrong: this last is `function returning pointer to int'. >I won't even bother with POINTER to FUNCTION returning POINTER to FUNCTION >returning an integer (the return value of signal() is one of these). Actually, the return value from signal is not representable, as it is `pointer to function returning pointer to function returning pointer to function returning ...', with no final type. Instead, we all cheat and use `pointer to function returning int' (or, in some cases, `returning void'). The program `cdecl' is handy for this sort of thing. It has been posted several times, so your neighbor probably has a copy, and it is available via anonymous FTP from host mimsy.umd.edu on the ARPAnet. % cdecl declare foo as pointer to function returning pointer to \ function returning int int (*(*foo)())() (cdecl does not handle `\' continuation lines; this is purely a mailer-bug-avoidance device) explain int (*(*foo)())() declare foo as pointer to function returning pointer to \ function returning int You can create horrendous things that no one ever would use: declare a as array 5 of pointer to function returning pointer to \ pointer to function returning pointer to array 3 of pointer to char char *(*(**(*a[5])())())[3] Amaze your friends by getting types like this right the first time! -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: seismo!mimsy!chris
jai@im4u.UUCP (Jai Srinivasan) (05/10/87)
In article <857@killer.UUCP>, John Haugh (jfh@killer.UUCP) writes: > The parenthesis come in real handy at times, for example (small lesson in > C to follow :-) when you can't figure out how to declare a 'something' with > a weird shape. My weakness is pointers to functions - > int foo (); /* this is a function */ > int *foo (); /* this is a function RETURNING a pointer */ > int *(foo ()); /* pointer to first function */ int *foo(); and int *(foo()); are equivalent because the () has a higher precedence than the * in the declaration. To make foo a pointer to a function which returns an integer, the declaration ought to be int (*foo)();. I guess the same holds with the array declarations stated earlier in that article because [] (like ()) has a higher precedence than the *. Reading these declarations is not all that hard: just use the precedence rules. The parentheses around the * in int (*foo)(); indicates that the * should be interpreted before the (), and reading "*" as "pointer to" and "()" as "function that returns", one reads int *foo(); as "foo is a function that returns a pointer to an integer", and int (*foo)(); as "foo is a pointer to a function that returns an integer". Similarly, int (*signal())(); is read as "signal is a function that returns a pointer to a function which returns an integer". I don't know if K&R ever explicitly state that the precedence rules hold in the declaraions as well, but I assume they do. Jai. ----------------- Jai Srinivasan, UUCP: {gatech,harvard,ihnp4,pyramid,seismo}!ut-sally!im4u!jai ARPA: jai@im4u.UTEXAS.EDU, jai@sally.UTEXAS.EDU
sjoerd@cs.vu.nl (Sjoerd Mullender) (05/12/87)
In article <6611@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >Actually, the return value from signal is not representable, >as it is `pointer to function returning pointer to function >returning pointer to function returning ...', with no final >type. Instead, we all cheat and use `pointer to function >returning int' (or, in some cases, `returning void'). We'll all agree that signal returns a pointer to some sort of function. That function is the signal handler for a certain signal. This means that it is int function (or sometimes void). So signal is a function returning a pointer to a function returning int (or void). In other words: int (*signal())(); -- Sjoerd Mullender sjoerd@cs.vu.nl
john@viper.UUCP (05/12/87)
In article <857@killer.UUCP> jfh@killer.UUCP (John Haugh) writes: >In article <3537@vrdxhq.UUCP>, tom@vrdxhq.UUCP (Tom Welsh) writes: >> >> I want to do the following : >> >> >> int *aa[]; >This is not a pointer to an array. This is an array of pointers. So, >the assignment >> aa = 0x50000; >doesn't make much sense. If you want a pointer to an array, you could >try >int **aa; Correct so far.... > If you REALLY want a pointer to an array, how about >int *(aa[]); How about because it's not a pointer to an array? A pointer to an array of int would be: int (*aa)[]; What you gave ( int *(aa[]); ) is identical to ( int *aa[]; ) which is actualy an array of pointers to ints... The [] binds to aa with a higher precedence than the *. > My weakness is pointers to functions - So I see... If it's any consolation, it's taken me a few years to get to the point where I get them right most of the time. I know many programmers who're excelent programmers, but even after 5-10 years they still get function pointers wrong now and then... I suspect the problem Tom Welsh is having is from the incorrect (but often used) habit some programmers have of defining a pointer to an array of pointers in-the-parameter-list as: foo(aa) int *aa[]; { .... Now, because C "knows" that you can't pass an array, it translates the *aa[] into **aa but doesn't tell the programmer about it. Any reference to aa[x] is (per standard C) corectly converted to *(aa+x) which will work for an array or a pointer. Unfortunately for Tom, this doesn't work anywhere except as part of the parameter list. If you have the sample I gave above, then aa = (int**)0x50000; will work with no problem, but it won't work at-all if you try it with a non-function-argument variable since the identifier aa will then refer to a non-moveable array. Your best bet is to correctly define it as int **aa; in the first place and avoid using the [] for for a pointer in parameter lists to avoid future confusion... >I won't even bother with POINTER to FUNCTION returning POINTER to FUNCTION >returning an integer. Just for the hell of it... B-) ...: int (*((*foo)()))(); >Disclaimer: > I don't have the slightest idea what I am talking about. I can't > handle these problems either. Oh... (falseto voice) "Nevermind..." :) --- John Stanley (john@viper.UUCP) Software Consultant - DynaSoft Systems UUCP: ...{amdahl,ihnp4,rutgers}!{meccts,dayton}!viper!john
chris@mimsy.UUCP (Chris Torek) (05/13/87)
In article <6611@mimsy.UUCP> I wrote some nonsense about signal. Ignore it. Thanks to sjoerd@cs.vu.nl (Sjoerd Mullender) for catching that. (enter exposition) I was thinking of a particular sort of `onexit' function, wherein each function returns a pointer to another function. Each of these functions is called until one returns a nil pointer: /* from <onexit.h>: typedef void (*onexit_t)(); * `cheating' */ onexit_t module_lastexit; onexit_t module_cleanup(); module_setup() { ... /* arrange to have module_cleanup called at exit */ module_lastexit = onexit(module_cleanup); /* and remember whatever was registered before us */ } onexit_t module_cleanup() { /* clean up */ ... /* and have exit do the previously registered function */ return (module_lastexit); } Exit then has a loop of the form while (doatexit != NULL) /* note the odd cast required */ doatexit = (*(onexit_t *(*)())doatexit)(); and the onexit function itself reads onexit_t onexit(f) onexit_t f; { onexit_t olddo = doatexit; doatexit = f; return (olddo); } (exit exposition) How I got this confused with signal I have no idea. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: seismo!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/13/87)
In article <266@sjoerd.cs.vu.nl> sjoerd@cs.vu.nl (Sjoerd Mullender) writes: >In article <6611@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >>Actually, the return value from signal is not representable, >>as it is `pointer to function returning pointer to function >>returning pointer to function returning ...', with no final >>type. Instead, we all cheat and use `pointer to function >>returning int' (or, in some cases, `returning void'). >We'll all agree that signal returns a pointer to some sort of function. >That function is the signal handler for a certain signal. This means >that it is int function (or sometimes void). So signal is a function >returning a pointer to a function returning int (or void). >In other words: > int (*signal())(); Sjoerd is right, except that the return type of a signal handler function is void, not int. Use of int dates back to the days before there was a void type; we have finally in the past couple of years gotten the standards to agree that void is the correct type. There are still several implementations that haven't updated their signal.h, however. I don't know what Chris had in mind. The only standard function I've seen in recent years that had such a problem with recursive type was the X3J11 onexit() function, which registered functions to be called upon exit. Each such function was supposed to keep track of the next in the chain, which is where the recursive type came from. Fortunately we managed to get this function changed to atexit() which has a much simpler inerface. If you were to consider the parameter types as part of a function's type, then signal() would of necessity have recursive type.