1839248 Members
3069 Online
110137 Solutions
New Discussion

Pascal to C Porting

 
SOLVED
Go to solution
Greg White
Frequent Advisor

Pascal to C Porting

I am porting a large analysis package from Pascal to C. Unfortunately while I have many years of experience in Pascal, I am very much a novice in C.

Many of my functions and procedures require the use of conformant arrays. I can't find any references to them in my C books. What do I do?

Thanks
I know how to do it in pascal.
14 REPLIES 14
A. Clay Stephenson
Acclaimed Contributor
Solution

Re: Pascal to C Porting

Hi Pascal:

I don't suppose a Pascal to C translator is an option. I've used several that almost work well although the quality of the code they produce is somewhat less than optimal in terms of readability. You are in luck in that I've done C for a very long time and Pascal for about 10 years though the last I did was sometime in the early 90's.

To answer you specific question - there ain't none. Rule Number 1: C don't care nothing about no array boundaries. If you send in an array[-5..100] of integer as a paramter but the formal parameter is declared[0..5] (I'm using the Pascal syntax for clarity), C could care less. Forget everything about strong type checking in this context. Rule Number 2: All arrays are indexed from zero. Rule Number 3: Array boundary checking is your responsibilty; you will never see an array index out of bound error in C (unless you write it).

Typically in C, arrays are dynamically allocated and changed in size 'on the fly' much as a linked list is in Pascal. This approach tends to be more convenient in C and any of your arrays can be dynamically declared.

Now this is going to confuse you:
suppose I have a pointer to int, *pi. It turns out that if I point pi to an area of memory that is actually 100 integers, then *pi is the first integer but p[0] is the same thing!; p[1] is the next value. In C, arrays and pointers are pretty much interchangable.

Regards and good luck, Clay
If it ain't broke, I can fix that.
Greg White
Frequent Advisor

Re: Pascal to C Porting

Thanks for your quick response.

No I can't use a translator for the reasons you mentioned. Can you please show me an example of how to create a dynamic array?

Thanks again.
I know how to do it in pascal.
A. Clay Stephenson
Acclaimed Contributor

Re: Pascal to C Porting

Hi again:

In Pascal, you had new and dispose as built-ins. In C, we have malloc(),realloc(),calloc() for memory allocation and free() for deallocation. These are actually library functions rather than an integral part of the language. These functions rely on the underlying system call sbrk() but don't go there!

Here is a sample piece of code to setup an array of 100 structs (records to you):

#include

#define NRECS 100

extern int errno;

typedef struct MY_REC
{
char name[32];
int age;
double income;
} my_rec;

my_rec *arry = NULL;

/* Allocate 100 elements */

arry = (my_rec *) calloc((size_t) NRECS,sizeof(my_rec));

/* You should test if the allocation was ok. */

if (arry != NULL)
{
/* populate the array */
int i = 0;

while (i < NRECS)
{
(void) sprintf(arry[i].name,"Test Name %d",i + 1);
arry[i].age = i + 10;
arry[i].income = i * 1000.0;
++i;
}
/* Now let's return the space to the heap and NULL the pointer as a flag for us */
free((void *) arry);
arry = NULL;
}
else (void) fprintf(stderr,"Calloc failed %d\n",errno);

That should give you an idea, note the heavy use of casting and also that while we declared arry as a pointer we actually USED it as an array.

Food for thought, Clay
If it ain't broke, I can fix that.
Greg White
Frequent Advisor

Re: Pascal to C Porting

Thanks again Clay. You confused me with the sprintf. What's that?
I know how to do it in pascal.
A. Clay Stephenson
Acclaimed Contributor

Re: Pascal to C Porting

Oh no you don't! You are not getting me to explain printf(),sprintf(),fprintf(), and vprintf()!!! Someone else will have to do that.
The bad news is that you MUST learn and understand these functions. The formatting conventions will drive you nuts initially. Man printf() for details. You really have to master these function very early in learning C but most C texts at least get you started.
You are going to find out just how much WRITE() and WRITELN() did for you behind the scens. In C++, the cout does a lot of the typing for you and is much more like Pascal I/O in that respect. The good news is that the printf()'s give you great power in formattin data.

Perhap's someone else would like to give a try with printf().

Regards, Clay
If it ain't broke, I can fix that.
Greg White
Frequent Advisor

Re: Pascal to C Porting

Thanks again for your answers. I have one more question of a general nature. My current Pascal code has heavily nested procedures and functions. I can't seem to declare my functions the same way in C.

For example,

Procedure AAA(var a)

Function BBB
End; {BBB}

Procedure CCC
End; {CCC}

End; {AAA}

In this case all variables within AAA should be visible to BBB and CCC but BBB and CCC should not be visible outside AAA.

I know how to do it in pascal.
Wodisch
Honored Contributor

Re: Pascal to C Porting

Hello,

if want "nesting" of functions/procedures then you
will not be able to use C. You might get a little closer
with classes in C++, but it is cumbersome to emulate
plain nesting with sub-classing...
Anyway, have you considered using C++ instead of C?
I do not see the point in learning plain old C, when you
already have programming experience and want to go
for something with a *future*; C will be there for many
years, true, but C++ is available almost everywhere (at
least where C is available, too) and the new release 3
of the GNU C/C++ compiler looks very promising.

Just my ?0.02,
Wodisch
A. Clay Stephenson
Acclaimed Contributor

Re: Pascal to C Porting

I tend to agree, that if you need heavily nested functions C++ classes are the better answer. I'm of the school that believes you must first master ANSI/C before the transition to C++. I can show you some of the ways to do what you like in C but the practical limit in C is 1 level. In your example, it is possible to do what you want but if either BBB or CCC have functions nested in turn that need to see variables in AAA then you are out of luck. Are you interested in any of these techniques?

Clay
If it ain't broke, I can fix that.
Greg White
Frequent Advisor

Re: Pascal to C Porting

Thanks both of you. I'm amazed at the responses I've gotten so far! The requirements for this project are cast in stone and cannot be changed. The code must be ported to ansi C. So back to my last question, is there any method I can use for nested procedures?

Thanks
I know how to do it in pascal.
A. Clay Stephenson
Acclaimed Contributor

Re: Pascal to C Porting

Hi Pascal,

The nesting of procedures in C can be done at some level. The typical Pacal program was one rather large compilation unit with all the code in one file with perhaps some includes which amounts to the same thing. Most Pascal's had UNITS which were pre-compiled. The INTEFACE section was needed at compile time and the UNIT itself was linked into the code to produce the executable.

Large scale C projects are done quite differently. A program might consist of 50 or more small source files which are compiled separately and then linked to form the executable. The difficultly here is that many of the source file interdepend on one another so that changing one can affect many others. While the use of the 'make' utility is convenient in Pascal it is absolutely essential in large-scale C. The dependencies must be correct so that if a crucial header file is changed averything is recompiled. If only one C source file is changed then only it needs to be recompiled and then the objects are re-linked.

Having said that I will now answer your question:

static int local_var = 0;

static int BBB(int i)
{
(void) printf("Function BBB i = %d\n",i);
local_var += i;
return(i);
} /* CCC */

static int CCC(int i)
{
(void) printf("Function CCC i = %d\n",i);
local_var -= i;
return(i);
} /* CCC */

int AAA(int a)
{
int cc = 0;

local_var = a;
cc = AAA(10);
if (cc > 0)
{
int dd = 0; /* NOTE Block-scope variable !!! */

dd = CCC(4);
}
return(cc);
} /* AAA */

Note the use of the Storage Class Specifier 'static'. In this context, local_var and the functions BBB and CCC are not visible
outside of this code fragment and are said to have 'file scope'. AAA is visible to the outside world. Notice that I copied AAA's parameter a to local_var so that BBB and CCC can operate on it. This is the extent of nesting in C. The scoping rules for variables are just like Pascal. The nearest reference wins.

What you do is extend this concept over many files. The other Storage Class Specifier you should explore is 'extern'. This allows global scope variables to be decalred once and accessed in any code module.

Regards, Clay
If it ain't broke, I can fix that.
Greg White
Frequent Advisor

Re: Pascal to C Porting

Thank you again, Clay

I thought static meant that a variable kept its value after the function finished unlike a 'regular' variable.

I already have scripts to compile and link my Pascal code. Won't that work just as well and be less complicated than your 'make' utility?

Dale
I know how to do it in pascal.
A. Clay Stephenson
Acclaimed Contributor

Re: Pascal to C Porting

Hi Dale:

You are quite correct. Static means exactly that unlike the 'auto' storage class specifier which behave just like the local Pascal variables that you are used to. Static variables are one of C's best features. However, 'static' also means just what I said earlier. Ain't C wonderful?

The answer to your second questions is NO - that dog won't hunt. If you have to split your program into many files there is no way that you can do that in a script and keep the program stable. There are simply too many dependencies. Make looks at the timestamps of your source files and objects (binaries) to determine what needs to be done to what. I suppose if you were a super shell programmer, you could do the same thing but why re-invent the wheel. Man make for details. It won't be enough to learn how to use it but it will get you started. I use a very old AT&T Programmer's Guide for my make reference but perhaps someone else can suggest a good make reference. A final point: be very careful resetting the time on your development box; you can really mess up the file datestamps that way. In general, it's a bad idea anyway to reset the time on a UNIX box.

Regards, Clay
If it ain't broke, I can fix that.
Greg White
Frequent Advisor

Re: Pascal to C Porting

Ok. It looks like I have even more homework to do. Does anybody have a sample input file for 'make' so I can see what it's supposed to do.

Thanks
I know how to do it in pascal.
A. Clay Stephenson
Acclaimed Contributor

Re: Pascal to C Porting

Okay Dale,

I 've attached one that's of medium complexity. It's actually a Makefile to build a yppasswd replacement with an option to push it out to several remote servers via rcp. The placement of is very critical to a makefile and is one of the few cases in UNIX textfiles where matter. Eight spaces ain't the same thing!!

I will give you a hint to understanding how this is supposed to work. If I modify main.c, only main.c gets recompiled to create a new main.o and then yppasswd gets relinked. If I modify local.h everything (except the libraries) gets recompiled and then yppasswd is relinked.

Hopefully someone else can share some more examples.

Regards, Clay
If it ain't broke, I can fix that.