elrond@titan.tsd.arlut.utexas.edu (Brad Hlista) (10/28/89)
I am having a problem of getting an allocated block of far memory
to return float values. Here is how variables are declared and dereferenced:
far *ptr;
main()
{
int i;
ptr=(float *) farmalloc(100000);
f(i=0;i<1000;i++)
*(ptr+i)=3.1415927;
for(i=0;i<10;i++)
printf(" %f", (float) *(ptr+i) ) ; /* is yielding 3.00000 */
}
Can someone please help me understand what is going on?
Thanks.
Brad
elrond@titan.tsd.arlut.utexas.edu
jwright@atanasoff.cs.iastate.edu (Jim Wright) (10/29/89)
In a recent posting elrond@titan.tsd.arlut.utexas.edu (Brad Hlista) writes: | I am having a problem of getting an allocated block of far memory | to return float values. Here is how variables are declared and dereferenced: | far *ptr; I think this is the big part. An int pointer is not the same as a float pointer. The following program works for me (MSC). #include <stdio.h> #include <malloc.h> int main(void); int main() { int i; float far *start; float far *p; start = (float far *) _fmalloc(1000*sizeof(float)); if (start != NULL) { printf("Good.\n"); for (p=start,i=0 ; i<1000 ; i++) *(p++) = 3.1415927; for (p=start,i=0 ; i<10 ; i++) printf("%f\n", *(p++)); } else printf("Oh shit.\n"); return(0); } -- Jim Wright jwright@atanasoff.cs.iastate.edu
bdb@becker.UUCP (Bruce Becker) (10/29/89)
In article <565@titan.tsd.arlut.utexas.edu> elrond@titan.tsd.arlut.utexas.edu (Brad Hlista) writes: |I am having a problem of getting an allocated block of far memory |to return float values. Here is how variables are declared and dereferenced: | |far *ptr; | |main() |{ |int i; | | ptr=(float *) farmalloc(100000); | | f(i=0;i<1000;i++) | *(ptr+i)=3.1415927; Should be: *((float *)(ptr+i)) = 3.1415927; Otherwise the "far" declaration of "ptr" will force a type conversion to the default of type "int". The way you have it the contents of of *(ptr+i)" contains an int value which is coerced back to float in the printf statement. | for(i=0;i<10;i++) | printf(" %f", (float) *(ptr+i) ) ; /* is yielding 3.00000 */ Should be printf(" %f", *((float *)(ptr+i)) ) ; /* is yielding 3.1415927 */ |} | |Can someone please help me understand what is going on? |Thanks. You need to ensure that either by default or by explicit declaration that sizeof(far) == sizeof(float); is there a "far long" type? Better yet, a "far float"? I didn't actually try this so if your compiler barfs on "*((float *)ptr)" where "ptr" is a "far *" declaration, well... you could try "far float * ptr;", etc... Cheers, -- .::. Bruce Becker Toronto, Ont. w \@@/ Internet: bdb@becker.UUCP, bruce@gpu.utcs.toronto.edu `/c/-e BitNet: BECKER@HUMBER.BITNET _/ \_ In the future the term "wife" will have no gender significance
CMH117@PSUVM.BITNET (Charles Hannum) (10/29/89)
Two suggestions: 1) Your main problem is that you need to use the declaration: far float *ptr; I won't even try to explain what happens otherwise. 2) You really should use "ptr[i]" rather than "*(ptr+i)". It effectively does the same thing, but it makes for much cleaner and much more readable code.
hp0p+@andrew.cmu.edu (Hokkun Pang) (10/31/89)
> 2) You really should use "ptr[i]" rather than "*(ptr+i)". It effectively > does the same thing, but it makes for much cleaner and much more > readable code. I read from a book that "ptr[i]" will be converted to "*(ptr+i)" by the compiler, so the "*(ptr+1)" is faster than "ptr[1]". Is that right?
spolsky-joel@CS.YALE.EDU (Joel Spolsky) (10/31/89)
In article <wZHEDrW00VoH479lIM@andrew.cmu.edu> hp0p+@andrew.cmu.edu (Hokkun Pang) writes: >> 2) You really should use "ptr[i]" rather than "*(ptr+i)". It effectively >> does the same thing, but it makes for much cleaner and much more >> readable code. > >I read from a book that "ptr[i]" will be converted to "*(ptr+i)" by the >compiler, so the "*(ptr+1)" is faster than "ptr[1]". Is that right? That's ridiculous. *(A+1), A[1], and 1[A] all produce exactly the same code. There is no reason to believe that the compiler prefers one over the other, or that the compiler implements A[1] by first expanding that to *(A+1). For all you know it does the opposite. And even if it did make a difference, it would be so small as to be imperceivable even on the worlds slowest C compiler running on an HP-41C. +----------------+----------------------------------------------------------+ | Joel Spolsky | bitnet: spolsky@yalecs.bitnet uucp: ...!yale!spolsky | | | internet: spolsky@cs.yale.edu voicenet: 203-436-1538 | +----------------+----------------------------------------------------------+ #include <disclaimer.h>
levitte@garbo.bion.kth.se (Tommy Levitte) (10/31/89)
In article <990@becker.UUCP> bdb@becker.UUCP (Bruce Becker) writes: Bruce> Xref: sics.se alt.msdos.programmer:153 comp.sys.ibm.pc:29919 Bruce> In article <565@titan.tsd.arlut.utexas.edu> elrond@titan.tsd.arlut.utexas.edu (Brad Hlista) writes: Bruce> |far *ptr; Bruce> |main() [... unimportant things deleted ...] Bruce> | f(i=0;i<1000;i++) Bruce> | *(ptr+i)=3.1415927; Bruce> Should be: *((float *)(ptr+i)) = 3.1415927; (* GAACK *) This means you should use the i'th INTEGER location, not float! Wow. The effect when printing out would be quite a sight... No, the correct syntax would be : *((float *)ptr + i) This way, you tell the compiler that ptr really is a float pointer, then offset the whole thing with i. In your solution, the offset would be 2*i bytes (2 = sizeof(int)). In mine, the offset would be 4*i bytes (4=sizeof(float)) !!!! Bruce> | for(i=0;i<10;i++) Bruce> | printf(" %f", (float) *(ptr+i) ) ; /* is yielding 3.00000 */ Bruce> Should be printf(" %f", *((float *)(ptr+i)) ) ; /* is yielding 3.1415927 */ Likewise here. Use *((float)ptr + i) instead ! Bruce> sizeof(far) == sizeof(float); is there a Bruce> "far long" type? Better yet, a "far float"? Wow. sizeof(far) ! Never seen that before. This would mean 'far int', which is not (as far as I know) permitted in TC. far is only applied on pointer and functions, to tell the compiler you need a 4-byte adress to get those objects. Thus, far is a modifier, not a type. Now, about int. int is the same as short in TC, a 2-byte integer. float is a 4-byte float. One IMPORTANT rule when you program in C: NEVER assume anything about the size of differnet types. NEVER !!!!! Bruce> I didn't actually try this so if your compiler Bruce> barfs on "*((float *)ptr)" where "ptr" is a Bruce> "far *" declaration, well... you could try Bruce> "far float * ptr;", etc... Quite surprising. I just tried it with Turbo C v 2.0, writing *((float *)ptr+i), and it worked just nice. writing *((float *)(ptr+i)) gave me 0.000000 when I tried it... -- Tommy Levitte gizmo@nada.kth.se gizmo@kicki.stacken.kth.se gizmo@ttt.kth.se
hollen@eta.megatek.uucp (Dion Hollenbeck) (11/01/89)
From article <990@becker.UUCP>, by bdb@becker.UUCP (Bruce Becker): > In article <565@titan.tsd.arlut.utexas.edu> elrond@titan.tsd.arlut.utexas.edu (Brad Hlista) writes: > |I am having a problem of getting an allocated block of far memory > |to return float values. Here is how variables are declared and dereferenced: > | > |far *ptr; > | > |main() > |{ > |int i; > | > | ptr=(float *) farmalloc(100000); > | > | f(i=0;i<1000;i++) > | *(ptr+i)=3.1415927; > > Should be: *((float *)(ptr+i)) = 3.1415927; > > Otherwise the "far" declaration of "ptr" > will force a type conversion to the default > of type "int". If the pointer is declared to be of type "float far *" then the statement "ptr + i" says "ptr + sizeof(type of ptr)*i" even though i is an int. If this does not occur, then the compiler is broken. The program could be written thusly: main() { float far *ptr; ptr = (float *) farmalloc(100000); f(i=0;i<1000;i++) *(ptr+i)=3.1415927; } The key is to declare the pointer to be a far ptr to a type of float and incrementation and pointer arithmetic will work. Dion Hollenbeck (619) 455-5590 x2814 Megatek Corporation, 9645 Scranton Road, San Diego, CA 92121 uunet!megatek!hollen or hollen@megatek.uucp
dbin@norsat.UUCP (Dave Binette) (11/01/89)
In article <wZHEDrW00VoH479lIM@andrew.cmu.edu> hp0p+@andrew.cmu.edu (Hokkun Pang) writes: >I read from a book that "ptr[i]" will be converted to "*(ptr+i)" by the >compiler, so the "*(ptr+1)" is faster than "ptr[1]". Is that right? Its possible but not alwyays determinable. In fact it may depend on the compiler and the native CPU. Some CPU's handle array indexing more efficiently than pointers so in either case your kind of at the mercy of those who ported the compiler to your machine. -- OS2... The nightmare continues. uucp: {uunet,ubc-cs}!van-bc!norsat!dbin | 302-12886 78th Ave bbs: (604)597-4361 24/12/PEP/3 | Surrey BC CANADA voice: (604)597-6298 (Dave Binette) | V3W 8E7
johnl@esegue.segue.boston.ma.us (John R. Levine) (11/02/89)
In article <150@norsat.UUCP> dbin@norsat.UUCP (Dave Binette) writes: >In article <wZHEDrW00VoH479lIM@andrew.cmu.edu> hp0p+@andrew.cmu.edu (Hokkun Pang) writes: >>I read from a book that "ptr[i]" will be converted to "*(ptr+i)" by the >>compiler, so the "*(ptr+1)" is faster than "ptr[1]". Is that right? >... >Some CPU's handle array indexing more efficiently than pointers so in either >case your [sic] kind of at the mercy of those who ported the compiler to your >machine. Sheesh. The two expressions are defined by the language to mean exactly the same thing. Anywhere you can use one of them, you can use the other and get exactly the same result. A C compiler should generate exactly the same code for both. In practice, every C compiler that I have seen converts ptr[i] to *(ptr+i) at compile time, and then generates the code. (Well, actually, I once did see a compiler that generated different code, but it turned out to be a mutant PL/I compiler rather than a C compiler.) I suppose there might be some microscopic difference in compile speed between the two, but the runtime performance that most people worry about will be identical. This is one of the most frequently misunderstood parts of the C language. If you still aren't sure why the two expressions are equivalent, this would be a good time to go back and reread your C books. -- John R. Levine, Segue Software, POB 349, Cambridge MA 02238, +1 617 864 9650 johnl@esegue.segue.boston.ma.us, {ima|lotus|spdcc}!esegue!johnl Massachusetts has over 100,000 unlicensed drivers. -The Globe