Sign in Join

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

Mailing lists / fpc-pascal / 2011-03

Converting code from C++ to FP....

11 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

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

Bo Berglund

I have a bunch of C++ files containing math processing functions, which I need to convert to pascal.
But I have never programmed C++ (only ANSI C some 15 years ago) and I am stuck because of the syntax differences. It is all about the handling of data in arrays and I would be grateful for some hints on how to convert it.

Below is an example function from this file set.

I have deduced that the variables named g<something> are globally defined, but I don't know how to handle the following:

1) The second line in the loop contains the command std::max, how can that be translated? I have not found any class definition for "std" with a method "max"....

2) The parameter into the function is a pointer *A of type double. To me that indicates a value of some kind, but in the code it suddenly seems to appear as an array with indexing. What would be the proper pascal translation of this?

void ForwardModel::Decompose(double *A)
{
  int i, j, k, jBegin, band;
  __int64 jPos, kPos;
  double sum;
  band = gNumNodeYZ;
  kPos = 0;
  for (k=1; k<=gNumNodes; ++k)
  {
      kPos += band;
      jBegin = std::max(k-band, 1);
      jPos = (jBegin-1) * band;
      for (j=jBegin; j<k; ++j)
      {
          jPos += band;
          sum = 0.0;
          for (i=jBegin; i<j; ++i) sum += A[kPos+i-1] * A[jPos+i-1];
          A[kPos+j-1] = (A[kPos+j-1] - sum) / A[jPos+j-1];
      }
      sum = 0.0;
      for (j=jBegin; j<k; ++j) sum += A[kPos+j-1] * A[kPos+j-1];
      A[kPos+k-1] = sqrt(A[kPos+k-1] - sum);
  }
}

Crudely translated:

procedure Decompose(var A: double); <<== Should it be an array here?
var
  i, j, k, jBegin, band: integer;
  jPos, kPos: Int64;
  sum: double;
begin
  band = gNumNodeYZ;
  kPos = 0;
  for k:=1 to gNumNodes do
  begin
    kPos := kPos + band;
    jBegin := std::max(k-band, 1); <<== what to do here?
    jPos := (jBegin-1) * band;
    for j := jBeginto k-1 do
    begin
      jPos := jPos + band;
      sum := 0.0;
      for i := jBegin to j-1 do
        sum := sum + A[kPos+i-1] * A[jPos+i-1]; <<== array????
      A[kPos+j-1] := (A[kPos+j-1] - sum) / A[jPos+j-1];
    end
    sum := 0.0;
    for j := jBegin to k-1 do
      sum := sum + A[kPos+j-1] * A[kPos+j-1]; <<== array????
    A[kPos+k-1] := sqrt(A[kPos+k-1] - sum);
  end
end;
Bo Berglund Developer in Sweden

Reply by email

Aleksa Todorovic
to Bo Berglund
Bo Berglund wrote 5 lines
1) The second line in the loop contains the command std::max, how can that be translated? I have not found any class definition for "std" with a method "max"....

There is function Max in unit Math, so you could say:

jBegin := Max(k-band, 1);
2) The parameter into the function is a pointer *A of type double. To me that indicates a value of some kind, but in the code it suddenly seems to appear as an array with indexing. What would be the proper pascal translation of this?

Indeed. C doesn't actually have difference between pointer to some data and arrays. You could use open array:

procedure Decompose(var A: array of double);

Reply by email

Jeppe Johansen
to Aleksa Todorovic
Aleksa Todorovic wrote 9 lines
> 2) The parameter into the function is a pointer *A of type double. To > me that indicates a value of some kind, but in the code it suddenly > seems to appear as an array with indexing. What would be the proper > pascal translation of this? Indeed. C doesn't actually have difference between pointer to some data and arrays. You could use open array: procedure Decompose(var A: array of double);

Or you could use

procedure Decompose(A: pdouble);

That way it would be precisely the same as the C solution. You can array-index A the same way as in C(in some fpc modes)

Reply by email

Ingemar Ragnemalm
Jeppe Johansen wrote 19 lines
Den 19-03-2011 08:30, Aleksa Todorovic skrev: >> 2) The parameter into the function is a pointer *A of type double. To >> me that indicates a value of some kind, but in the code it suddenly >> seems to appear as an array with indexing. What would be the proper >> pascal translation of this? >> > Indeed. C doesn't actually have difference between pointer to some > data and arrays. You could use open array: > > procedure Decompose(var A: array of double); > Or you could use procedure Decompose(A: pdouble); That way it would be precisely the same as the C solution. You can array-index A the same way as in C(in some fpc modes)

I would only do that when mixing C and Pascal code, to interface with C code.
In a Pascal-only program, never. Converting bad C code (that means almost any C code)
to good FPC code is a great thing to do, converting to bad FPC code is not as much fun.

/Ingemar

Reply by email

Bo Berglund
to Aleksa Todorovic: There is function Max in unit Math, so you could say: jBegin := Max(k-band, 1); Indeed. C…
Aleksa Todorovic wrote 20 lines
On Sat, Mar 19, 2011 at 06:07, Bo Berglund wrote: > > 1) The second line in the loop contains the command std::max, how can > that be translated? I have not found any class definition for "std" > with a method "max".... > There is function Max in unit Math, so you could say: jBegin := Max(k-band, 1); > 2) The parameter into the function is a pointer *A of type double. To > me that indicates a value of some kind, but in the code it suddenly > seems to appear as an array with indexing. What would be the proper > pascal translation of this? Indeed. C doesn't actually have difference between pointer to some data and arrays. You could use open array: procedure Decompose(var A: array of double);

Thanks for the information!
Now I have found another very strange construct:

void ForwardModel::SetMixedBoundaryCondition(const int iElec, const double* SX0,
const double* SY0,
const double* SZ0,
double* SX,
double* SY,
double* SZ)

Now it seems like the variable type declaration itself is a pointer....

Instead of double *Name it is double* Name. What is the difference? It is still being used as an array:

          SX[n1] = SX0[n1] * (1.0 - w1);

Does C++ allow any placement of the * operator with the same meaning?

And what does const double* mean? Pointer to some object but not allowed to change that object????

Having programmed Delphi for 16 years this is hard to wrap ones head around. :-(

Bo Berglund Developer in Sweden

Reply by email

Aleksa Todorovic
to Bo Berglund: On Sat, 19 Mar 2011 08:30:45 +0100, Aleksa Todorovic Thanks for the information! Now I…
Bo Berglund wrote 25 lines
Now I have found another very strange construct: void ForwardModel::SetMixedBoundaryCondition(const int iElec,   const double* SX0,   const double* SY0,   const double* SZ0,   double* SX,   double* SY,   double* SZ) Now it seems like the variable type declaration itself is a pointer.... Instead of double *Name it is double* Name. What is the difference? It is still being used as an array:          SX[n1] = SX0[n1] * (1.0 - w1); Does C++ allow any placement of the * operator with the same meaning? And what does const double* mean? Pointer to some object but not allowed to change that object???? Having programmed Delphi for 16 years this is hard to wrap ones head around. :-(

Welcome to the world of Chell ;-) I (unfortunately) have to use it daily. Ok, not let's be helpful.

In the situation above, const has similar meaning as the one in Pascal
- you have some value which you are not allowed to change. So, your header should be something like:

procedure ForwardModel.SetMixedBoundaryCondition(const iElec :
Integer; const SX0, SY0, SZ0 : array of double; var SX, SY, SZ : array
of double);

Hint: if you use trunk version of FPC, I suggest you use constref to ensure SX0, SY0 and SZ0 are passed as pointer.

procedure ForwardModel.SetMixedBoundaryCondition(const iElec :
Integer; constref SX0, SY0, SZ0 : array of double; var SX, SY, SZ :
array of double);

As Jeppe suggested, you can also use pointers:

procedure ForwardModel.SetMixedBoundaryCondition(const iElec :
Integer; const SX0, SY0, SZ0 : pdouble; SX, SY, SZ : pdouble);

Reply by email

Bo Berglund
to Jürgen Hestermann: Yes, when already in progress of converting to Pascal then get rid of C design flaws and…
Jürgen Hestermann wrote 9 lines
Ingemar Ragnemalm schrieb: > Converting bad C code (that means almost any C code) > to good FPC code is a great thing to do, converting to bad FPC code is > not as much fun. Yes, when already in progress of converting to Pascal then get rid of C design flaws and convert to clear Pascal code.

That is indeed my aim! :-)

Bo Berglund Developer in Sweden

Reply by email

Jorge Aldo G. de F. Junior
to Bo Berglund

no one explained so let me try :

void ForwardModel::SetMixedBoundaryCondition(const int iElec,

void somefunction means its a pascal procedure

const double* SX0,

const has the same effect as fpc const before a parameter,

double* SX0
is the same as
double *SX0
or
double * SX0

so this becomes

const SX0 : pdouble (ugly pointer as array Cishism)

const double* SY0,

const SY0 : pdouble

const double* SZ0,

idem

double* SX, double* SY, double* SZ)
SX : pdouble;

etc

Reply by email

Bo Berglund
to Jorge Aldo G. de F. Junior
"Jorge Aldo G. de F. Junior" wrote 35 lines
no one explained so let me try : > void ForwardModel::SetMixedBoundaryCondition(const int iElec, void somefunction means its a pascal procedure > const double* SX0, const has the same effect as fpc const before a parameter, double* SX0 is the same as double *SX0 or double * SX0 so this becomes const SX0 : pdouble (ugly pointer as array Cishism) > const double* SY0, const SY0 : pdouble > const double* SZ0, idem > double* SX, > double* SY, > double* SZ) SX : pdouble; etc

Thanks! :-)

Bo Berglund Developer in Sweden

Reply by email

Micha Nelissen
to Jorge Aldo G. de F. Junior: no one explained so let me try : void somefunction means its a pascal procedure const has…
Jorge Aldo G. de F. Junior wrote
const has the same effect as fpc const before a parameter,

This is not true.

Show quoted text 9 lines
double* SX0 is the same as double *SX0 or double * SX0 so this becomes const SX0 : pdouble (ugly pointer as array Cishism)

No! 'const double * X' in C makes the pointed-to data const, while 'const X: PDouble' in pascal makes the parameter itself const. You cannot assign another address of a double to it, while you can in C.

In C terms, pascal can only do 'double * const X'. Pascal is not really useful this way, 'const' is generally only useful for structures and strings.

Micha

Reply by email