Hi, Is it possible to use universal pointer like void* in C? I have seen that there is a keyword "univ" with sun compiler. How to do to have universal pointer with gpc? thanks
On 18 Feb 2003 at 11:07, Mehdi Khaldi wrote:
Hi, Is it possible to use universal pointer like void* in C?
"Pointer"
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
Mehdi Khaldi wrote:
Hi, Is it possible to use universal pointer like void* in C? I have seen that there is a keyword "univ" with sun compiler. How to do to have universal pointer with gpc?
"Pointer"
Frank Heckenbach wrote:
Adriaan van Os wrote:
(7) Filter out a handful of compiler features that would really assist GPC development on Mac OS X (and porting from CodeWarrior). On this list wil be UNIV parameters, I guess, but this is premature.
No idea what they are ...
Like the Sun compiler, Macintosh Pascal compilers have the UNIV keyword. UNIV is put before the type (after the colon) in parameter lists and says "don't complain if the types of actual parameter and formal parameter don't match, as long as they have the same sizes in bytes".
Please note that this is more restrictive than Delphi's untyped variables (which are not typed and sized at all, and therefore VAR parameters only).
Use of UNIV is not restricted to universal pointers, although in actual practice that is indeed the most common case. With the "Pointer" type in GPC, I found a case that doesn't work.
Consider the following three cases (see the testprogram below for details).
(1) typed pointer passed as value parameter. Works in GPC and Delphi. (2) typed pointer passed as variable parameter. Works in GPC, but not in Delphi. (3) typed pointer in procedural parameter list passed as actual parameter. Works not in GPC and not in Delphi.
All three cases work in Macintosh Pascal compilers (with UNIV attached to the pointer type).
Regards,
Adriaan van Os
---------
program testuniv;
type rec = record a: integer; b: longint end; recptr = ^rec; ord4 = cardinal( 32); var gr : rec; gp : recptr;
{$X+} procedure incptr( var p: {univ} pointer); begin p:= p + 1 end;
procedure writeptr( p: {univ} pointer); begin writeln( 'p = ', ord4( p)) end;
procedure writerec( rp: recptr); begin writeln( 'a = ', rp^.a, ', b = ', rp^.b) end;
procedure writebyptr( pp: {univ} pointer; procedure pwrite( p: {univ} pointer)); begin pwrite( pp) end;
begin gr.a := 123; gr.b := 456; gp := @gr; writerec ( gp); writeptr ( gp); incptr ( gp); writebyptr( gp, writeptr); writebyptr( gp, writerec) { <--- not allowed by GPC compiler } end.
On 18 Feb 2003 at 20:48, Adriaan van Os wrote:
[...] (3) typed pointer in procedural parameter list passed as actual
parameter. Works not in GPC and not in Delphi.
And IMHO, it shouldn't.
All three cases work in Macintosh Pascal compilers (with UNIV attached to the pointer type).
I doubt the value of such a feature. This is the type of thing that typecasts for absolute variables can be used for.
e.g., instead of this: procedure writerec( rp: recptr); begin writeln( 'a = ', rp^.a, ', b = ', rp^.b) end;
you can have this: procedure writerec( p: pointer); var rp : recptr absolute p; begin writeln( 'a = ', rp^.a, ', b = ', rp^.b) end;
or this: procedure writerec( rp: pointer); begin writeln( 'a = ', recptr (rp)^.a, ', b = ', recptr (rp)^.b) end;
At the risk of trying to teach one's grandmother how to suck eggs, these seem to me to be less error prone. They also make it clearer what one is actually doing and do not require changes to the compiler. However, for the sake of compatibility, it might be worth implementing (I personally remain unconvinced - but I guess that this is a matter for Frank).
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
At the risk of trying to teach one's grandmother how to suck eggs, these seem to me to be less error prone.
In another mailing list, I found the sentence ... "But it's a chicken-and-egg issue; until Mach-O does this, no Mach-O partisan will understand." The same here. It is difficult to appreciate a feature from a world you haven't entered. You get used to the work-around or my-way-to-do-it, where the guy from the other world relies on it.
The example program was designed to be as short as possible, not to be in any way useful or convincing ...
I agree that typecasts and absolute variables can do the job. But that holds for **any** use of untyped pointers. So, are untyped pointers an elegant or a dangerous feature ? Well, I could argue pro and contra .... The programmer has to make a decision on a case by case basis.
GPC **has** untyped pointers and I don't think that case (3) is opposite to their purpose and intentions.
Regards,
Adriaan van Os
Adriaan van Os wrote:
Prof A Olowofoyeku (The African Chief) wrote:
Mehdi Khaldi wrote:
Hi, Is it possible to use universal pointer like void* in C? I have seen that there is a keyword "univ" with sun compiler. How to do to have universal pointer with gpc?
"Pointer"
Frank Heckenbach wrote:
Adriaan van Os wrote:
(7) Filter out a handful of compiler features that would really assist GPC development on Mac OS X (and porting from CodeWarrior). On this list wil be UNIV parameters, I guess, but this is premature.
No idea what they are ...
Like the Sun compiler, Macintosh Pascal compilers have the UNIV keyword. UNIV is put before the type (after the colon) in parameter lists and says "don't complain if the types of actual parameter and formal parameter don't match, as long as they have the same sizes in bytes".
You may remeber that I heavily criticized some Borland features lately. Well, I like this one even less. First, it adds a new keyword. I think that many dialects (also Borland, in other cases) are adding keywords far too quickly. Most of us know the drawbacks. BP's untyped parameters need no new keyword (though a new syntax rule, which is also not nice, but not as bad as a new keyword), and a `Void' type parameter which I'd prefer (semantically equivalent to BP's untyped parameters) would do neither (just a predefined identifier which can simply be redefined).
Secondly, it demands the same size. That's unportable! Pascal doesn't make any statements about type sizes, so you have the effect that a program may compile on one platform and not on another. Sure, you can get such dependencies also by "unclean" code -- but for a core feature (even one manifested in the syntax), sorry no!
The restriction itself is also highly dubious. E.g., on my machine `ShortReal' has the same size as `Integer'. So what? With intimate knowledge of floating point formats, I may be able to do something with a `ShortReal' masked as `Integer' -- and this will break badly on many platforms for many reasons (size, endianness, FP format, ...). So I think if you do such low-level bit-fiddling, you should just tell the compiler that you know what you're doing and to leave you alone, rather than some pseudo-typing or whatever we should call this which may give you a wrong impression of safety ...
Prof A Olowofoyeku (The African Chief) wrote:
On 18 Feb 2003 at 20:48, Adriaan van Os wrote:
[...] (3) typed pointer in procedural parameter list passed as actual
parameter. Works not in GPC and not in Delphi.
And IMHO, it shouldn't.
I agree. What seems to be done is to infer compatibility of procedural parameter types from assignment compatibility of their arguments. That's not quite in the spirit of Pascal where already two distinct types, both declared as `array [1 .. 10] of Integer' are not compatible at all, leave alone arrays of different, though assignment-compatible types. I don't think this should be any less strict for procedural types.
It's also less safe: In your example, `writerec' expects its argument to be of type `recptr'. But the procedural parameter usage breaks this. That's unlike `writeptr' where the procedure declares its argument so, so the implementation of the procedure can handle the issue. So the extension of procedural types basically allows you to pass anything to any parameter, without any explicit type-casts or such (which would make the possible dangers obvious).
Frank