azarian@hpcc01.HP.COM (Randy Azarian) (06/01/90)
Can I assign an address of a variable to the value of a standard integer? Like so: { int a,d; a=&d; bdos(1,a,1); } This works, but gives me the following warning: warning C4047: '=' : different levels of indirection By doing: { int d; bdos(1,&d,1); } also works (and as far as I'm concerned, equivalent), but gives me the following two warnings: warning C4047: 'argument' : different levels of indirection warning C4024: 'bdos' : different types : parameter 2 The address should only contain the offset value (having the segment value of the DS register), and should therefore be an integer, and should assign to a declared integer. The is for PC's (Microsoft C 6.0), and I realize that it is probably different from other machines. I suppose I only wish to eliminate the warning messages, because my programs function fine. Is there another way to achieve what I want using pointers?
henry@utzoo.uucp (Henry Spencer) (06/02/90)
In article <1280003@hpcc01.HP.COM> azarian@hpcc01.HP.COM (Randy Azarian) writes: >Can I assign an address of a variable to the value of a standard integer? Any sensible compiler will reject this as a type mismatch. The address of a variable of type T is of type "pointer to T". This is not an integer type, and cannot be assigned to an integer variable. If you know what you are doing, the correct way to accomplish this is by casting the address to an integer type: i = (int) &x; The result of this is very implementation-specific and you need to know what your compiler is going to do about it. -- As a user I'll take speed over| Henry Spencer at U of Toronto Zoology features any day. -A.Tanenbaum| uunet!attcan!utzoo!henry henry@zoo.toronto.edu
hollen@megatek.UUCP (Dion Hollenbeck) (06/02/90)
From article <1280003@hpcc01.HP.COM>, by azarian@hpcc01.HP.COM (Randy Azarian): > Can I assign an address of a variable to the value of a standard integer? > { > int a,d; > a=&d; > bdos(1,a,1); > } > This works, but gives me the following warning: > warning C4047: '=' : different levels of indirection You can get rid of the problem by casting it: a = (int)&d ; We do this all the time when passing addresses as "magic cookies". We obtain them and do the cast. They are then stored as ints and passed around as ints. When they finally get to the function which needs them, they are cast back to a pointer of the proper type. -- Dion Hollenbeck (619) 455-5590 x2814 Megatek Corporation, 9645 Scranton Road, San Diego, CA 92121 uunet!megatek!hollen or hollen@megatek.uucp
chrisj@netcom.UUCP (Christopher T. Jewell) (06/02/90)
In article <486@tau.megatek.uucp> hollen@megatek.UUCP (Dion Hollenbeck) writes: >From article <1280003@hpcc01.HP.COM>, by azarian@hpcc01.HP.COM (Randy Azarian): >> Can I assign an address of a variable to the value of a standard integer? >> { >> int a,d; >> a=&d; >> bdos(1,a,1); >> } >> This works, but gives me the following warning: >> warning C4047: '=' : different levels of indirection > > >You can get rid of the problem by casting it: > > a = (int)&d ; > >We do this all the time when passing addresses as "magic cookies". >We obtain them and do the cast. They are then stored as ints and >passed around as ints. When they finally get to the function >which needs them, they are cast back to a pointer of the proper >type. Well, yeah, that will work on some systems. On others, such as ms-dos with large model, you will lose half your bits when you do the cast, since a pointer is 32 bits and an int is 16. (Randy's code, containing a call to something called bdos(), looks like it could suffer from such problems.) It's not even defined whether you will lose the most significant 16 bits, or the least significant, or even all the odd-numbered bits. <grin> In brief, the results are undefined. It's much safer to pass your magic cookies around as void pointers (or char pointers for old compilers). (Or you could do the whole thing in Modula-2, and just make them opaque types, but let's not start another language-religion war. :-) ) -- Chris (Christopher T. Jewell) chrisj@netcom.uucp apple!netcom!chrisj
kitchin@hpavla.AVO.HP.COM (Bruce Kitchin) (06/06/90)
{ int a,d; a=&d; bdos(1,a,1); } The problem is that &d is not of type int. Others have suggested that you say (int)&d. This happens to make my blood boil. I don't know how many 'portable' programs including this from GNU that I've tried to port to MSDOS that made the assumption that sizeof(int) == sizeof(int *). That is simply not portable and on some machines such as 80x86 will only work in limited cases. According to K&R (page 210), "A pointer may be converted to any of the integral types large enough to hold it. Whether an int or long is required is machine dependent." Having wasted many hours trying to find all of the places in 'portable' programs that this bad assumption has been made, sizeof(int) == sizeof(int *), I have trouble with converting pointers to int's. Having gotten that off my chest, let's look at your problem. If I am making the correct assumption, bdos looks like an MSDOS interface function. The only MSDOS functions that this can call are those that take a DS relative address (ie., near address). To use this function you must assure that the program is compiled as a Small model program or that d is located in the defaultdata segment. Unless the program is compiled for DS != SS, all stack allocated variables are default data segment (all non-static local variables in your functions, for example, and all function arguments). If you are sure that these assumptions are true then you can do something like: { int far *a; int d; a = &d bdos(1,FP_OFF(a),1); } where FP_OFF is defined in dos.h. Otherwise you should use the intdos function in which you supply the segment registers as well as the ordinary registers to the int 0x21 call. Since this is a dos interface, you may want to see if your compiler's library has a more specific dos call to do what you are after. For function 1, getche() suggests itself. There are also a number of functions supplied by MSC and Turbo-C for Dos specific interfaces.