Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2005-06

using oldlinux

11 messages · 8 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Koenraad Lelong

Hi,
Anyone has suggestions why I can't compile the following :

unit test1;
interface
function ReadCOM(portnum : integer; inlen : integer; var inbuf : array
of byte) : integer;
implementation
uses baseunix, oldlinux;
function ReadCOM(portnum : integer; inlen : integer; var inbuf : array
of byte) : integer;
var
  fd : integer;
  filedescr : TFDSet;
  tval : timeval;
  cnt : integer;
  timeout : boolean;
begin
  fpFD_ZERO(filedescr);
  fpFD_SET(fd,filedescr);
  tval.sec:=0;
  tval.usec:=10000;
  if fpSelect(fd+1,@filedescr,nil,nil,@tval)>0 then
   if fpread(fd,inbuf[cnt],1)1 then
    timeout:=true
   else
    inc(cnt)
  else timeout:=true;
if not timeout then
  ReadCom:=inlen
else
  ReadCom:=cnt;
end;
end.

I'm getting the following error :
test1(22,21) Error: call by var parameters have to match exactly: Got "fdSet" expected "TFDSet"
test1(23,23) Error: call by var parameters have to match exactly: Got "fdSet" expected "TFDSet"
I changed filedescr to fdset and back to TFDSet with the same result. That's with FPC 2.0.0.
TIA
Koenraad Lelong.

Marco van de Voort
to Koenraad Lelong
Anyone has suggestions why I can't compile the following :

tfdset and or (t)timeval maybe exists in both baseunix and oldlinux. Why do you use oldlinux at all?

use baseunix.tfdset and baseunix.ttimeval or so. See the fpselect example in the documentation.

Michael Van Canneyt
to Koenraad Lelong: Anyone has suggestions why I can't compile the following : unit test1; interface function…
Koenraad Lelong wrote 13 lines
Hi, Anyone has suggestions why I can't compile the following : unit test1; interface function ReadCOM(portnum : integer; inlen : integer; var inbuf : array of byte) : integer; implementation uses baseunix, oldlinux;

You must switch the order of the units, because you get the 'oldlinux' types which you try to use in 'baseunix' functions.

You can drop the oldlinux altogether. The program compiles as follows:

uses baseunix,unixtype;
function ReadCOM(portnum : integer; inlen : integer; var inbuf : array of byte) : integer;
var
fd : integer;
filedescr : TFDSet;
tval : timeval;
cnt : integer;
timeout : boolean;
begin
fpFD_ZERO(filedescr);
fpFD_SET(fd,filedescr);
tval.tv_sec:=0;
tval.tv_usec:=10000;
if fpSelect(fd+1,@filedescr,nil,nil,@tval)>0 then
  if fpread(fd,inbuf[cnt],1)1 then
timeout:=true
else
 inc(cnt)
 else timeout:=true;
if not timeout then
 ReadCom:=inlen
else
 ReadCom:=cnt;
end;
begin
end.
Alain Vitry
to Michael Van Canneyt
Michael Van Canneyt wrote 6 lines
You must switch the order of the units, because you get the 'oldlinux' types which you try to use in 'baseunix' functions.

This unit order trick is a bit of a wizardery to me. It quickly get very messy in a large enough program to swap units order until you get the one which doesn't break.
In the sw I'm porting, almost every single UPI type is re-defined in many units, which makes FPC complain about types.
Am I missing some switches or some pascal features, with my kernel hacker mind ?

Regards,
Alain

Jonas Maebe
to Alain Vitry
Alain Vitry wrote 5 lines
> You must switch the order of the units, because you get the > 'oldlinux' types which > you try to use in 'baseunix' functions. This unit order trick is a bit of a wizardery to me.

It's simply: the last included unit overrides all previously included units.

It quickly get very messy in a large enough program to swap units order until you get the one which doesn't break.

The proper solution is to not use old compatibility units (such as aldlinux) and the replacements (baseunix, unix) in the same program.

Jonas

Vincent Snijders
to Alain Vitry: This unit order trick is a bit of a wizardery to me. It quickly get very messy in a large…
Alain Vitry wrote 17 lines
Le 14 juin 05, à 09:46, Michael Van Canneyt a écrit : > > You must switch the order of the units, because you get the 'oldlinux' > types which > you try to use in 'baseunix' functions. > > This unit order trick is a bit of a wizardery to me. It quickly get very messy in a large enough program to swap units order until you get the one which doesn't break. In the sw I'm porting, almost every single UPI type is re-defined in many units, which makes FPC complain about types. Am I missing some switches or some pascal features, with my kernel hacker mind ?

You can also specify from which unit you want to use the type/procedure/function/constant.

Suppose both unit A and unit B declare a procedure DoIt;
You could do something like this:
program p;
uses A, B;
begin
   A.DoIt; // calls DoIt in unit a
   B.DoIt; // calss DoIt in unit b
end;

Vincent.

Alain Vitry
to Vincent Snijders

Thanks for the answer.

But is that by design ?

Let' look at this case (not the best design, but big legacy):

File common.pas:
uses  StandardFile, MacWindows;
...
var MaPict: array[WPictWind_1..WPictWind_3] of PicHandle;
File utils.pas:
uses commons, MacWindows, SegLoad, Quickdraw, StandardFile;
...
var PictRect: Rect;
...
DrawPicture(PictArray[i], PictRect);

Compilation:
Utils.pas(316,29) Error: Incompatible type for arg no. 1: Got "MACWINDOWS.PicHandle", expected "STANDARDFILE.PicHandle"

I know about unit propagation. PicHandle is first defined in MacWindows, then used in standardfile.
The best solution I've found is to suffle units around, altough I find this approach inelegant.
Renaming every occurence of some types is a better solution, altough very intrusive.

Shouldn't type A defined in unit X be fixed whether units Y, Z who also use it are included or not in my program ?
Also when unit Y defines a procedure with type A (from unit X) as parameter, shouldn't type A still refer to the type A as defined in unit X, and not become some types like Y.A ?

It is unclear to me, why this problem occur in the first place (In this case there is no re-definition of the types, as for oldlinux)

Kind regards,
Alain

Vincent Snijders wrote 37 lines
Alain Vitry wrote: > Le 14 juin 05, à 09:46, Michael Van Canneyt a écrit : >> >> You must switch the order of the units, because you get the >> 'oldlinux' types which >> you try to use in 'baseunix' functions. >> >> > This unit order trick is a bit of a wizardery to me. It quickly get > very messy in a large enough program to swap units order until you > get the one which doesn't break. > In the sw I'm porting, almost every single UPI type is re-defined in > many units, which makes FPC complain about types. > Am I missing some switches or some pascal features, with my kernel > hacker mind ? You can also specify from which unit you want to use the type/procedure/function/constant. Suppose both unit A and unit B declare a procedure DoIt; You could do something like this: program p; uses A, B; begin A.DoIt; // calls DoIt in unit a B.DoIt; // calss DoIt in unit b end; Vincent. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Vincent Snijders
to Alain Vitry
Alain Vitry wrote 25 lines
Thanks for the answer. But is that by design ? Let' look at this case (not the best design, but big legacy): File common.pas: uses StandardFile, MacWindows; ... var MaPict: array[WPictWind_1..WPictWind_3] of PicHandle; File utils.pas: uses commons, MacWindows, SegLoad, Quickdraw, StandardFile; ... var PictRect: Rect; ... DrawPicture(PictArray[i], PictRect); Compilation: Utils.pas(316,29) Error: Incompatible type for arg no. 1: Got "MACWINDOWS.PicHandle", expected "STANDARDFILE.PicHandle" I know about unit propagation. PicHandle is first defined in MacWindows, then used in standardfile.

Used or redefined? Does the StandardFile unit also use the MacWindows unit?

Show quoted text 10 lines
The best solution I've found is to suffle units around, altough I find this approach inelegant. Renaming every occurence of some types is a better solution, altough very intrusive. Shouldn't type A defined in unit X be fixed whether units Y, Z who also use it are included or not in my program ? Also when unit Y defines a procedure with type A (from unit X) as parameter, shouldn't type A still refer to the type A as defined in unit X, and not become some types like Y.A ?

If I understood you correctly, yes. There is Y.A unless you define such a type.

It is unclear to me, why this problem occur in the first place (In this case there is no re-definition of the types, as for oldlinux)

It is unclear to me too.

Vincent.

Jonas Maebe
to Alain Vitry: Thanks for the answer. But is that by design ? Let' look at this case (not the best…
Alain Vitry wrote
I know about unit propagation.

Note that FPC at this time does not support uses propagation, so only the types exported directly by the units in the uses clauses of the current compilation unit are visible.

PicHandle is first defined in MacWindows, then used in standardfile.

It is also defined in standardfile, because standardfile includes dialogs.p which in turn includes quickdraw.p, and PicHandle is defined in quickdraw.p

The best solution I've found is to suffle units around, altough I find this approach inelegant.

So is the fact that these types are redeclared in all units over and over again. I think the easiest solution would be to replace all those units by "carbon". Then everything is defined in one unit and you shouldn't have any further problems with this anymore.

Shouldn't type A defined in unit X be fixed whether units Y, Z who also use it are included or not in my program ?

That is the case. The problem is simply the C-like inclusion of Pascal "header" files by which the Universal Interfaces are plagued. In C, you do not have namespaces so it doesn't matter. This is different for Pascal. But if you simply use the carbon unit everywhere, you won't have this problem.

Jonas

Matt Emson
to Alain Vitry: Thanks for the answer. But is that by design ? Let' look at this case (not the best…

Not a perfect solution, but the following solutions work:

1) create a unit for all clashing types to live in. Move all types that clash to this central point and then use this unit anywhere that the clash occurs.

2) use the following trick in your local code:
  type TMyclashingType = UnitIWantToUse.TMyClashingType;
  so in your case:
  type PicHandle = common.PicHandle;

Solution 1 is more favourable though. Solution 2 will only work if luck is on your side and you do not require procedures or functions from both units that take the type as a param. Mind you, the above could be defined as:

type CommonPicHandle = common.PicHandle;
type FileUtilsPicHandle = FileUtils.PicHandle;

and so long as you do not use any structures based on them, all will be fine. Structures (records) may also allow this trick, but then it's getting into scoping issues and that can sometimes change from compiler to complier, so I will not claim it will work.

All of this may or may not require Delphi mode - it certainly works in Delphi mode.

Matt

Michalis Kamburelis
to Matt Emson

Matt Emson wrote:
[...]

Show quoted text 10 lines
2) use the following trick in your local code: type TMyclashingType = UnitIWantToUse.TMyClashingType; so in your case: type PicHandle = common.PicHandle; Solution 1 is more favourable though. Solution 2 will only work if luck is on your side and you do not require procedures or functions from both units that take the type as a param.

[...]

Actually, you can also do this trick with procedures or functions (although this time it's really really dirty trick):

Suppose you have MyFunction declared in MyUnit unit. You want to export MyFunction in other unit that uses MyUnit:

const
   MyFunction: function(... MyFunction params...): ...MyFunction
result... = MyUnit.MyFunction;