(Go: >> BACK << -|- >> HOME <<)

Comparison of Pascal and C: Difference between revisions

Content deleted Content added
Monkbot (talk | contribs)
m Task 18 (cosmetic): eval 1 template: hyphenate params (1×);
Bapoux (talk | contribs)
m →‎Later Pascal implementations and extensions: reference to type casts in Free Pascal added
 
(42 intermediate revisions by 20 users not shown)
Line 1:
{{Short description|Comparison of two programming languages}}
{{Multiple issues|
{{more footnotes needed|date=June 2013}}
{{original research|date=September 2015}}
}}
 
{{ProgLangCompare}}
The computer [[programming language]]s [[C (programming language)|C]] and [[Pascal (programming language)|Pascal]] have similar times of origin, influences, and purposes. Both were used to design (and compile) their own compilers early in their lifetimes. The original Pascal definition appeared in 1969 and a first compiler in 1970. The first version of C appeared in 1972.
Line 15:
[[Programming language syntax|Syntactically]], Pascal is much more ALGOL-like than [[C syntax|C]]. English keywords are retained where C uses punctuation symbols – Pascal has <code>and</code>, <code>or</code>, and <code>mod</code> where C uses <code>&&</code>, <code>||</code>, and <code>%</code> for example. However, C is more ALGOL-like than Pascal regarding (simple) declarations, retaining the ''type-name'' ''variable-name'' syntax. For example, C can accept declarations at the start of any block, not just the outer block of a function.
 
=== Semicolon use ===
Another, more subtle, difference is the role of the [[semicolon]]. In Pascal, semicolons ''separate'' individual statements within a compound statement; instead in C, they ''terminate'' the statement. In C, they are also syntactically part of the statement (transforming an expression into a statement). This difference manifests mainly in two situations:
 
Line 23:
A superfluous semicolon can be put on the last line before '''end''', thereby formally inserting an ''empty statement''.
 
=== Comments ===
In traditional C, there are only <code>/* block comments */</code>. This is only supported by certain Pascal dialects like MIDletPascal.
 
Line 29:
Modern Pascal, like Object Pascal (Delphi, FPC), as well as modern C implementations allow C++ style comments <code>// line comments</code>
 
=== Identifiers and keywords ===
C and Pascal differ in their interpretation of upper and lower case. C is case sensitive while Pascal is not, thus <code>MyLabel</code> and <code>mylabel</code> are distinct names in C but identical in Pascal. In both languages, identifiers consist of letters and digits, with the rule that the first character may not be a digit. In C, the underscore counts as a letter, so even _abc is a valid name. Names with a leading underscore are often used to differentiate special system identifiers in C.
 
Both C and Pascal use [[Reserved word|keywords]] (words reserved for use by the language). Examples are '''if''', '''while''', '''const''', '''for''' and '''goto''', which are keywords that happen to be common to both languages. In C, the basic built-in type names are also keywords (e.g., '''int''', '''char''') or combinations of keywords (e.g., '''unsigned char'''), while in Pascal the built-in type names are predefined normal identifiers.
 
=== Definitions, declarations, and blocks ===
In Pascal, [[subroutine|procedure]] definitions start with keywords '''procedure''' (no value returned) or '''function''' (a value is returned) and [[Data type|type definitions]] with '''type'''. In C, all subroutines have <code>function</code> definitions are(procedures determinedbeing by<code>void syntacticalfunction</code>s) context whileand type definitions use the keyword <code>typedef</code>. Both languages use a mix of keywords and punctuation for definitions of complex types; for instance, arrays are defined by the keyword '''array''' in Pascal and by punctuation in C, while [[enumeration]]s are defined by the keyword <code>enum</code> in C but by punctuation in Pascal.
 
In Pascal functionssubroutines, '''begin''' and '''end''' delimit a block of statements (proper)preceded by local declarations, while C functions use "{" and "}" to delimit a block of statements optionally preceded by declarations. : C (before C99) strictly defines that any declarations must occur ''before'' the statements within a particular block but allows blocks to appear within blocks, which is a way to go around this. PascalBy isits strictsyntax of a subroutine's body, Pascal enforces that declarations must occur before statements,. butPascal also allows ''definitions'' of types and functions{{snd}}not only variable declarations{{snd}} to be encapsulated by function definitions to any level of depth.
 
=== Implementation ===
The grammars of both languages are of a similar size. From an implementation perspective the main difference between the two languages is that to [[parsing|parse]] C it is necessary to have access to a symbol table for types, while in Pascal there is only one such construct, assignment. For instance, the C fragment <code>X * Y;</code> could be a declaration of <code>Y</code> to be an object whose type is pointer to <code>X</code>, or a statement-expression that multiplies <code>X</code> and <code>Y</code>. In contrast, the corresponding Pascal fragmentfragments <code>'''var''' Y : ^X;</code> isand <code>Z := X * Y;</code> are inherently unambiguous; correct parsing does not require a symbol table.
 
== Simple types ==
{{unreferenced section|date=June 2013}}
 
=== Integers ===
Pascal requires all variable and function declarations to specify their type explicitly. In traditional C, a type name may be omitted in most contexts and the default type <code>int</code> (which corresponds to <code>[[integer]]</code> in Pascal) is then implicitly assumed (however, such defaults are considered bad practice in C and are often flagged by warnings).
 
C accommodates different sizes and [[signedness|signed and unsigned]] modes for integers by using modifiers such as <code>long</code>, <code>short</code>, <code>signed</code>, <code>unsigned</code>, etc. The exact meaning of the resulting integer type is machine-dependent, however, what ''can'' be guaranteed is that <code>long int </code> is atno leastshorter 16 bits,than <code>longint</code> and <code>int</code> is no shorter than <code>short int</code>. andHowever, in C standard, there are at least minimal sizes of types are specified which guarantees <code>short intchar</code> isto nobe longera thansingle [[byte]] and <code>int</code> to be at least two bytes.
 
=== Subranges ===
In Pascal, a similar end is performed by declaring a ''subrange'' of integer (a compiler may then choose to allocate a smaller amount of storage for the declared variable):
 
Line 65:
In C, operands must first be promoted to the size of the required result: intermediate results are undefined if they do not fit into the range of the promoted operands. If range of the required result is greater than the range of operands, this normally produces slow inefficient code, even from a good optimising compiler. However, a C compiler is never required or expected to handle out of range intermediate results: it is the programmers responsibility to ensure that all intermediate results fit into the operand range.
 
The (only) prePre-Standard implementationimplementations of C as well as Small-C et al. allowed integer and [[pointer (computer programming)|pointer]] types to be relatively freely intermixed.
 
=== Character types ===
Line 81:
 
=== Boolean types ===
In Pascal, '''[[Boolean datatype|boolean]]''' is an enumerated type. The possible values of '''boolean''' are '''false''' and '''true''', with ordinal value of false&nbsp;=&nbsp;0 and true&nbsp;=&nbsp;1. For conversion to '''integer''', '''ord''' is used:
 
<syntaxhighlight lang="pascal">
Line 93:
</syntaxhighlight>
 
C has no '''[[Boolean datatype|boolean]]''' type. C uses binary valued relational operators (<, >, ==, !=, <=, >=) which may be regarded as ''boolean'' in the sense that they always give results which are either zero or one. As all tests (&&, ||, ?:, '''if''', '''while''', etc.) are performed by zero-checks, '''false''' is represented by zero, while '''true''' is represented by any other value. This is visible in the <code>bool</code> numeric datatype defined in <code>stdbool.h</code>.
 
==== Bitwise operations ====
C allows using [[bitwise operation|bitwise]] [[operator (programming)|operators]] to perform boolean operations. Care must be taken because the semantics are different when operands make use of more than one bit to represent a value.
 
Pascal has another more abstract, high level method of dealing with bitwise data, '''sets'''. Sets allow the programmer to set, clear, intersect, and unite bitwise data values, rather than using direct bitwise operators (which are available in modern Pascal as well). Example;
 
Pascal:
<syntaxhighlight lang="pascal">
Status := Status + [StickyFlag];
Line 112:
</syntaxhighlight>
 
C:
<syntaxhighlight lang="c">
Status |= StickyFlag;
Line 121:
Although bit operations on integers and operations on sets can be considered similar if the sets are implemented using bits, there is no direct parallel between their uses unless a non-standard conversion between integers and sets is possible.
 
==== A note on implementation ====
During expression evaluation, and in ''both languages'', a boolean value may be internally stored as a single bit, a single byte, a full machine word, a position in the generated code, or as a condition code in a status register, depending on machine, compiler, and situation; these factors are usually more important than the language compiled.
 
Line 128:
 
=== Enumeration types ===
Both C and Pascal include enumeration types. A Pascal example:
 
<syntaxhighlight lang="pascal">
Line 144:
</syntaxhighlight>
 
The behavior of the types in the two languages however is very different. In Pascal enumerations are ordinal and parsed using <code>ord()</code>, <code>succ()</code> and <code>pred()</code> functions and are distinct from the <code>array</code> structure. In C, enumerations are in fact implemented as <code>arrays</code> and <code>red</code> becomes just a synonym for 0, <code>green</code> for 1, <code>blue</code> for 2, and nothing prevents a value outside this range to be assigned to the variable <code>a</code>. Furthermore, operations like <code>a = a + 1;</code> are strictly forbidden in Pascal; instead you would use <code>a := succ(a);</code>. In C, enums can be freely converted to and from ints, but in Pascal, the function <code>ord()</code> must be used to convert from enumerated types to integers, in opposite conversion must be used typecast operation like <code>a := color(1)</code> for <code>green</code> value return.
 
== Structured types ==
{{Unreferenced section|date=June 2013}}
 
Line 170:
Strings consisting of n (>1) characters are defined as packed arrays with range 1..n.
 
==== Arrays and pointers ====
In C expressions, an identifier representing an array is treated as a constant pointer to the first element of the array, thus, given the declarations <code>int a[10]</code> and <code>int *p;</code> the assignment <code>p = a</code> is valid and causes p and a to point to the same array. As the identifier <code>a</code> represents a ''constant'' address, <code>a = p</code> is not valid however.
 
While arrays in C are fixed, pointers to them are interchangeable. This flexibility allows C to manipulate any length array using the same code. It also leaves the programmer with the responsibility not to write outside the allocated array, as no checks are built in into the language.
 
In Pascal, arrays are a distinct type from pointers. This makes [[bounds checking]] for arrays possible from a compiler perspective. Practically all Pascal compilers support range checking as a compile ''option''.
The ability to both have arrays that change length at runtime, and be able to check them under language control, is often termed "dynamic arrays". In Pascal the number of elements in each array type is determined at compile-time and cannot be changed during the execution of the program. Hence, it is not possible to define an array whose length depends in any way on program data. (Note : since 1986 and Turbo Pascal 3, which was the industry standard, <code>GetMem()</code> allows dynamic arrays in everyday Pascal, if not in the ISO standard)
 
C has the ability to initialize arrays of arbitrary length. The <code>[[sizeof]]</code> operator can be used to obtain the size of a statically initialized array in C code. For instance in the following code, the terminating index for the loop automatically adjusts should the list of strings be changed.
Line 192:
</syntaxhighlight>
 
Likewise modern Pascal, e.g. Delphi and Free Pascal, has a similar ability. Initialized arrays can be implemented as:
Original Pascal has neither array initialization (outside of the case of strings) nor a means of determining arbitrary array sizes at compile time.
<syntaxhighlight lang="pascal">
var
wordlist: array of string = [
'print', 'out', 'the', 'text', 'message'];
i: Integer;
begin
for i := Low(wordlist) to High(wordlist) do
writeln(wordlist[i]);
for i := High(wordlist) downto Low(wordlist) do
writeln(wordlist[i]);
end.
</syntaxhighlight>
 
Original Pascal has neither array initialization (outside of the case of strings) nor a means of determining arbitrary array sizes at compile time. One way of implementing the above example in original Pascal, but without the automatic size adjustment, is:
 
<syntaxhighlight lang="pascal">
Line 257 ⟶ 269:
In Pascal, unlike C, the string's first character element is at index 1 and not 0 (leading it to be [[String (computer science)#Length-prefixed|length-prefixed]]). This is because Pascal stores the length of the string at the 0th element of the character array. If this difference is not well understood it can lead to errors when [[porting]] or trying to interface [[object code]] generated by both languages.
 
[[FreeBSD]] developer [[Poul-Henning Kamp]], writing in ''[[ACM Queue]]'', would later refer to the victory of null-terminated strings over length-prefixed strings as "the most expensive one-byte mistake" ever.<ref>{{citation |last=Kamp |first=Poul-Henning |date=25 July 2011 |title=The Most Expensive One-byte Mistake |journal=ACM Queue |volume=9 |number=7 |pages=40–43 |doi=10.1145/2001562.2010365 |s2cid=30282393 |issn=1542-7730 |access-date=2 August 2011 |url=http://queue.acm.org/detail.cfm?id=2010365 |doi-access=free }}</ref>
 
=== Record types ===
Line 268 ⟶ 280:
</syntaxhighlight>
<syntaxhighlight lang="pascal">
type a = record
b: integer;
c: char;
Line 274 ⟶ 286:
</syntaxhighlight>
 
In Pascal, we can use the sentence "'''with''' <''name_of_record>'' do" in order to use directly the fields of that record, like local variables, instead of write <''name_of_record>''.<''name_of_field>''. Here there is an example:
<syntaxhighlight lang="pascal">
type r = record
r = record
s: string;
c: char;
end;
var r1 : r;
r1 : r;
begin
with r1 do begin
s := 'foo';
c := 'b';
end;
</syntaxhighlight>
Line 323 ⟶ 333:
</syntaxhighlight>
Both language processors are free to allocate only as much space for these records as needed to contain the largest type in the union/record.
In Pascal, such constructs are called '''variant records''', not to be mistaken with the '''Variant''' datatype defined in Free Pascal.
 
The biggest difference between C and Pascal is that Pascal supports the [[Tagged union|explicit use of a "tagfield"]] for the language processor to determine if the valid component of the variant record is being accessed:
Line 332 ⟶ 343:
end;
</syntaxhighlight>
In this case, the tagfieldtag field q must be set to the right state to access the proper parts of the record.
 
== Pointers ==
Line 360 ⟶ 371:
To create dynamic data, the library functions <code>malloc()</code> and <code>free()</code> are used to obtain and release dynamic blocks of data. Thus, [[dynamic memory allocation]] is not built into the language processor. This is especially valuable when C is being used in operating system kernels or embedded targets as these things are very platform (not just architecture) specific and would require changing the C compiler for each platform (or operating system) that it would be used on.
 
Pascal doesn't havehas the same kind of pointers as C, butthrough itthe does<code>^</code> have an indirectionreferencing operator thatinstead coversof the most common use<code>*</code> of C pointers. Each pointer is bound to a single dynamic data item, and can only be moved by assignment:
 
<syntaxhighlight lang="pascal">
type a = ^integer;
 
var b, c: a;
 
new(b);
c := b;
Line 372 ⟶ 383:
 
Pointers in Pascal are type safe; i.e. a pointer to one data type can only be assigned to a pointer of the same data type. Also pointers can never be assigned to non-pointer variables. Pointer arithmetic (a common source of programming errors in C, especially when combined with [[endianness]] issues and platform-independent type sizes) is not permitted in Pascal.
All of these restrictions reduce the possibility of pointer-related errors in Pascal compared to C, but do not prevent invalid pointer references in Pascal altogether. For example, a runtime error will occur if a pointer is referenced before it has been initialized or after it has been disposed of.
 
== Expressions ==
{{unreferenced section|date=June 2013}}
 
=== Precedence levels ===
The languages differ significantly when it comes to expression evaluation, but all-in-all they are comparable.
 
''Pascal''
# ''Logical negation:'' <code>'''not'''</code>
# ''Multiplicative:'' <code>'''* / div mod and'''</code>
# ''Additive:'' <code>'''+ - or'''</code>
# ''Relational:'' <code>'''= <> < > <= >= in'''</code>
 
''C''
# ''Unary postfix:'' <code>'''[] () . -> ++ --'''</code>
# ''Unary prefix:'' <code>'''& * + - ! ~ ++ -- (type) [[sizeof]]'''</code>
# ''Multiplicative:'' <code>'''* / %'''</code>
# ''Additive:'' <code>'''+ -'''</code>
# ''Shift:'' <code>'''<< >>'''</code>
# ''Relational:'' <code>'''< > <= >='''</code>
# ''Equality:'' <code>'''== !='''</code>
# ''Bitwise and:'' <code>'''&'''</code>
# ''Bitwise xor:'' <code>'''^'''</code>
# ''Bitwise or:'' <code>'''|'''</code>
# ''Logical and:'' <code>'''&&'''</code>
# ''Logical or:'' <code>'''||'''</code>
# ''Conditional:'' <code>'''? :'''</code>
# ''Assignment:'' <code>'''= += -= *= /= %= <<= >>= &= ^= |='''</code>
# ''Comma operator'': <code>''','''</code>
 
=== Typing ===
Most operators serve several purposes in Pascal, for instance, the minus sign may be used for negation, subtraction, or set difference (depending on both type and syntactical context), the <code>&gt;=</code> operator may be used to compare numbers, strings, or sets, and so on. C uses dedicated operator symbols to a greater extent.
 
==== Assignment and equality tests ====
The two languages use different operators for assignment. Pascal, like [[ALGOL]], uses the mathematical equality operator <code>=</code> for the equality test and the symbol <code>:=</code> for assignment, whereas C, like [[B (programming language)|B]], uses the mathematical equality operator for assignment. In C (and B) the new <code>==</code> symbol wasof therefore[[FORTRAN]] was introducedchosen for the equality test.
 
It is a common mistake in C, due either to inexperience or to a simple typing error, to accidentally put assignment expressions in conditional statements such as <code>{{c-lang|1=if (a = 10) { ... }</code> }}. The code in braces will always execute because the assignment expression <code>a = 10</code> has the value 10 which is non-zero and therefore considered "true" in C; this is in part because C (and ALGOL) allow multiple assignment in the form <code>a = b = c = 10;</code> which is not supported by Pascal. Also note that <code>a</code> now has the value <code>10</code>, which may affect the following code. Recent C compilers try to detect these cases and warn the user, asking for a less ambiguous syntax like <code>{{c-lang|1=if ((a=10) != 0 ) { ... }</code> }}.
 
This kind of mistake cannot happen in Pascal, as assignments are not expressions and do not have a value: using the wrong operator will cause an unambiguous compilation error, and it's also less likely that anyone would mistake the <code>:=</code> symbol for an equality test.
 
It is notable that ALGOL's conditional expression in the form <{{code>a|2=pascal|1=z := if a > b then a else b;</code>}} has an equivalent in C (the [[Ternary conditional operator|ternary operator from CPL]]) but not in Pascal, which will use {{code|2=pascal|1=if a > b then z:=a; else z:=b;}}.
 
===Implementation issues===
When [[Niklaus Wirth]] designed Pascal, the desire was to limit the number of levels of precedence (fewer parse routines, after all). So the OR and exclusive OR operators are treated just like an Addop and processed at the level of a math expression. Similarly, the AND is treated like a Mulop and processed with Term. The precedence levels are
{{aligned table|cols=3|row1header=y|class=wikitable
<pre>
| Level | Syntax Element | Operator
<!------------------------------------------------------------>
 
| 0 | factor | literal, variable
| 1 | signed factor | unary minus, {{tt|NOT}}
| 2 | term | {{tt|*, /, AND}}
| 3 | expression | {{tt|+, -, OR}}
}}
</pre>
Notice that there is only ONE set of syntax rules, applying to both kinds of operators. According to this grammar, then, expressions like
<pre>
x + (y AND NOT z) / 3
</pre>
are perfectly legal. And, in fact, they are, as far as the parser is concerned. Pascal doesn'tdoes not allow the mixing of arithmetic and Boolean variables, and things like this are caught at the semantic level, when it comes time to generate code for them, rather than at the syntax level.
 
The authors of C took a diametrically opposite approach: they treat the operators as different, and in fact, in C there are no fewer than 15 levels. That's because C also has the operators '=', '+=' and its kin, '<<', '>>', '++', '--', etc. Although in C the arithmetic and Boolean operators are treated separately, the variables are not: a Boolean test can be made on any integer value.
 
==== Logical connectives ====
In Pascal a ''boolean'' expression that relies on a particular evaluation ordering (possibly via side-effects in function calls) is, more or less, regarded as an error. The Pascal compiler has the freedom to use whatever ordering it may prefer and must always evaluate the whole expression even if the result can be determined by partial evaluation. (Note: since Turbo Pascal 3 (1986) the short-circuit Boolean evaluation is available in everyday Pascal, if not in the ISO standard).
 
In C, dependence on ''boolean'' evaluation order is perfectly legal, and often systematically employed using the <code>&&</code> and <code>||</code> operators together with operators such as <code>++</code>, <code>+=</code>, the comma operator, etc. The <code>&&</code> and <code>||</code> operators thereby function as combinations of logical operators and conditional ''statements''.
 
Short circuit expression evaluation has been commonly considered an advantage for C because of the "evaluation problem":
Line 448 ⟶ 459:
...
</syntaxhighlight>
This seemingly straightforward search is problematic in Pascal because the array access a[i] would be invalid for i equal to 11.
There is more than one way to avoid this problem. The following example introduces a boolean variable which indicates whether or not the target character has been found:
<syntaxhighlight lang="pascal">
Line 460 ⟶ 471:
i := 1;
found := false;
while not found and (i <= strlen) do
if (a[i] = 'x') then found := true else i := i+1;
...
</syntaxhighlight>
Alternatively, the test for end of array can be separated from the array access and a goto statement can break out of the search if the target is found:
<syntaxhighlight lang="pascal">
label 99;
const
strlen = 10;
var i: integer;
a: packed array [1..strlen] of char;
...
i := 1;
repeat
if a[i] = 'x' then goto 99;
i := i+1
until i > strlen;
99:
...
</syntaxhighlight>
Line 467 ⟶ 495:
== Control structures ==
Statements for building control structures are roughly analogous and relatively similar (at least the first three).
{{aligned table|cols=2|row1header=y|class=wikitable
| 1=Pascal
| 3= <code>'''if''' ''cond'' '''then''' ''stmt'' '''else''' ''stmt''</code>
| 5= <code>'''while''' ''cond'' '''do''' ''stmt''</code>
| 7= <code>'''repeat''' ''stmt'' '''until''' ''cond''</code>
| 9= <code>'''for''' ''id'' := ''expr'' '''to''' ''expr'' '''do''' ''stmt''</code><br/>and<br /><code>'''for''' ''id'' := ''expr'' '''downto''' ''expr'' '''do''' ''stmt''</code>
|11= <code>'''case''' ''expr'' '''of'''<br/>{{quad}}''expr'' ''':''' ''stmt'';<br/>{{quad}}...<br/>{{quad}}''expr'' ''':''' ''stmt'';<br/>{{quad}}'''else:''' ''stmt'';<br/>'''end'''</code>
| 2=C
| 4= <code>'''if''' (''cond'') ''stmt'' '''else''' ''stmt''</code>
| 6= <code>'''while''' (''cond'') ''stmt''</code>
| 8= <code>'''do''' ''stmt'' '''while''' (''cond'');</code>
|10= <code>'''for''' (''expr''; ''cond''; ''expr'') ''stmt''</code>
|12= <code>'''switch''' (''expr'') {<br/>{{quad}}'''case''' ''expr'' ''':''' ''stmt'';<br/>{{quad}}...<br/>{{quad}}'''case''' ''expr'' ''':''' ''stmt'';<br/>{{quad}}'''default:''' ''stmt''<br/>}</code>
}}
Pascal, in its original form, did not have an equivalent to {{tt|default}}, but an equivalent <code>else</code> clause is a common extension. Pascal programmers otherwise had to guard case-statements with an expression such as: {{mono|'''if''' ''expr'' '''not''' '''in''' [A..B] '''then''' ''default-case''}}.
 
C has the so-called early-out statements {{tt|break}} and {{tt|continue}}, and some Pascals have them as well.
Pascal has:
*{{mono|'''if''' ''cond'' '''then''' ''stmt'' '''else''' ''stmt''}}
*{{mono|'''while''' ''cond'' '''do''' ''stmt''}}
*{{mono|'''repeat''' ''stmt'' '''until''' ''cond''}}
*{{mono|1='''for''' ''id'' := ''expr'' '''to''' ''expr'' '''do''' ''stmt'' and '''for''' ''id'' := ''expr'' '''downto''' ''expr'' '''do''' ''stmt''}}
*{{mono|'''case''' ''expr'' '''of''' ''expr'' ''':''' ''stmt''; ... ''expr'' ''':''' ''stmt''; '''else:''' ''stmt''; '''end'''}}
C has:
*{{mono|'''if''' (''cond'') ''stmt'' '''else''' ''stmt''}}
*{{mono|'''while''' (''cond'') ''stmt''}}
*{{mono|'''do''' ''stmt'' '''while''' (''cond'');}}
*{{mono|'''for''' (''expr''; ''cond''; ''expr'') ''stmt''}}
*{{mono|'''switch''' (''expr'') { '''case''' ''expr'' ''':''' ''stmt''; ... '''case''' ''expr'' ''':''' ''stmt''; '''default:''' ''stmt'' } }}
 
Pascal, in its original form, did not have an equivalent to '''default''', but an equivalent '''else''' clause is a common extension. Pascal programmers otherwise had to guard case-statements with an expression such as: {{mono|'''if''' ''expr'' '''not''' '''in''' [A..B] '''then''' ''default-case''}}.
 
C has the so-called early-out statements '''break''' and '''continue''', and some Pascals have them as well.
 
Both C and Pascal have a '''{{tt|goto'''}} statement. However, since Pascal has nested procedures/functions, jumps can be done from an inner procedure or function to the containing one; this was commonly used to implement error recovery. C has this ability via the ANSI C [[setjmp/longjmp|{{tt|setjmp}} and {{tt|longjmp}}]]. This is equivalent, but arguably less safe, since it stores program specific information like jump addresses and stack frames in a programmer accessible structure.
 
== Functions and procedures ==
Pascal routines that return a value are called functions; routines that don'tdo not return a value are called procedures. All routines in C are called functions; C functions that do not return a value are declared with a return type of ''[[void type|void]]''.
 
Pascal procedures are considered equivalent to C "void" functions, and Pascal functions are equivalent to C functions that return a value.
Line 504 ⟶ 532:
</syntaxhighlight>
 
Pascal has two different types of parameters: pass-by-value, and pass-by-reference (VAR). In both cases the variable name is used when calling (no need of address operator).
<syntaxhighlight lang="pascal">
function f(z: integer; var k: integer): integer; // function accepts two integers, one by value, one by reference
Begin
x := f(t);
z:=1; // outer variable u will not be modified, but local value is modified in the function's scope
k:=1; // outer variable t will be modified because it was passed by reference
// up to here, z exists and equals 1
End;
 
x := f(u,t); // the variables u and t are passed to the call : the value of u and the reference to t
</syntaxhighlight>
 
Line 513 ⟶ 547:
 
<syntaxhighlight lang="c">
int f(int z, int *k); { //function accepts an int (by value) and a pointer to int (also by value) as parameter
z=1; // idem Pascal, local value is modified but outer u will not be modified
x = f(&t);
*k=1; // variable referenced by k (eg, t) will be modified
// up to here, z exists and equals 1
}
 
x = f(u,&t); // the value of u and the (value of) address of variable t are passed to the call
</syntaxhighlight>
 
One of the most important difference between C and Pascal is the way they handle the parameters on stack during a subroutine call :
C allows for functions to accept a variable number of parameters, known as [[variadic function]]s.
This is called the '''calling convention''' :
PASCAL-style parameters are pushed on the stack in left-to-right order.
The STDCALL calling convention of C pushes the parameters on the stack in right-to-left order.
 
Pascal-style procedure call is made with :
* caller pushing parameters into the stack in left-to-right order (opposite of {{tt|__cdecl}})
* calling the function
* stack is cleaned up by the callee
 
<syntaxhighlight lang="nasm">
; example of pascal-style call.
; NOTE: __stdcall would push the arguments in reverse order.
push arg1
push arg2
push arg3
call function
; no stack cleanup upon return: callee did it
</syntaxhighlight>
The advantage of PASCAL call over STDCALL is that the code is slightly smaller, though the size impact is only visible in large programs, and that recursion works faster.
 
Variadic functions are almost impossible to get right with PASCAL and STDCALL methods, because only the caller really knows how many arguments were passed in order to clean them up.
 
C allows for functions to accept a variable number of parameters, known as [[variadic function]]s, using a clumsy mechanism of <code>va_list ap;</code>, <code>va_start(ap, count);</code>, <code>va_arg(ap, ''type'');</code> with limited ''type'' availability (example : nothing for <code>bool</code>)
 
<syntaxhighlight lang="c">
Line 524 ⟶ 586:
</syntaxhighlight>
 
The function <code>f()</code> uses a special set of functions (<code>varargs</code>) that allow it to access each of the parameters in turn.
 
Pascal and C also have some variadic I/O functions, for instance <code>WriteLn()</code> and <code>printf()</code>.
Additionally Pascal has I/O statements built into the language to handle variable amount of parameters, like <code>Writeln</code>. Pascal allows procedures and functions to be [[nested function|nested]]. This is convenient to allow variables that are local to a group of procedures, but not global. C lacks this feature and the localization of variables or functions can be done only for a compiling module wherein the variables or functions would have been declared '''static'''.
 
Modern Pascals enable a variable number of parameters for functions :
C allows functions to be indirectly invoked through a function pointer. In the following example, the statement <code>(*cmpar)(s1, s2)</code> is equivalent to <code>strcmp(s1, s2)</code>:
<syntaxhighlight lang="pascal">
procedure writeLines(const arguments: array of const); // parsed via : for argument in arguments do
</syntaxhighlight>
They also enable to interface with varargs C functions :
<syntaxhighlight lang="pascal">
Function PrintF1(fmt : pchar); cdecl; varargs; external 'c' name 'printf';
</syntaxhighlight>
 
Pascal allows procedures and functions to be [[nested function|nested]]. This is convenient to allow variables that are local to a group of procedures, but not global. C lacks this feature and the localization of variables or functions can be done only for a compiling module wherein the variables or functions would have been declared '''static'''.
 
C and Pascal allow functions to be indirectly invoked through a [[function pointer]]. In the following example, the statement <code>(*cmpar)(s1, s2)</code> is equivalent to <code>strcmp(s1, s2)</code>:
 
<syntaxhighlight lang="c">
Line 541 ⟶ 614:
</syntaxhighlight>
 
In Pascal also allows functions and procedures tocan be passed as parameters to functions or procedures:
<syntaxhighlight lang="pascal">
 
procedure ShowHex(i: integer);
...
Line 561 ⟶ 633:
Demo(ShowHex);
Demo(ShowInt);
...
</syntaxhighlight>
 
Line 568 ⟶ 639:
Early C had neither constant declarations nor type declarations, and the C language was originally defined as needing a "[[preprocessor]]"; a separate program, and pass, that handled constant, include and [[Macro (computer science)|macro]] definitions, to keep memory usage down. Later, with ANSI C, it obtained constant and type definitions features and the preprocessor also became part of the language, leading to the syntax we see today.
 
Pascal constant and type defines are built in, butand theredon't need a preprocessor.
There were programmers using a preprocessor also with Pascal (sometimes the same one used with C), certainly not as common as with C. Although often pointed out as a "lack" in Pascal, technically C doesn'tdoes not have program modularity nor macros built in either. It has a simple low level separate compilation facility, however (traditionally using the same generic linker used for assembly language), Pascal does not.
 
== Type escapes ==
Line 593 ⟶ 665:
end;
</syntaxhighlight>
Although casting is possible on most Pascal compilers and interpreters, even in the code above a2c.a and a2c.b aren'tare not required by any Pascal standardizations to share the same address space. Niklaus Wirth, the designer of Pascal, has written about the problematic nature of attempting type escapes using this approach:
 
"Most implementors of Pascal decided that this checking would be too expensive, enlarging code and deteriorating program efficiency. As a consequence, the variant record became a favourite feature to breach the type system by all programmers in love with tricks, which usually turn into pitfalls and calamities".
Line 600 ⟶ 672:
 
== Files ==
In C files do not exist as a built-in type (they are defined in a system header) and all I/O takes place via library calls. Pascal has file handling built into the language.
 
The typical statements used to perform I/O in each language are:
Line 612 ⟶ 684:
</syntaxhighlight>
 
The main difference is that C uses a "format string" that is interpreted to find the arguments to the printf function and convert them, whereas Pascal performs that under the control of the language processor. The Pascal method is arguably faster, because no interpretation takes place, but the C method is highly extensible.
 
== Later Pascal implementations and extensions ==
Some popular Pascal implementations have incorporated virtually all C constructs into Pascal. Examples include type casts,<ref>{{Cite web |title=Typecast - Lazarus wiki |url=https://wiki.freepascal.org/Typecast |access-date=2024-05-18 |website=wiki.freepascal.org}}</ref> being able to obtain the address of any variable, local or global, and different types of integers with special promotion properties.
 
However, the incorporation of C's lenient attitude towards types and type conversions can result in a Pascal that loses some or all of its type security. For example, [[Java (programming language)|Java]] and [[C Sharp (programming language)|C#]] were created in part to address some of the perceived type security issues of C, and have "managed" pointers that cannot be used to create invalid references. In its original form (as described by [[Niklaus Wirth]]), Pascal qualifies as a managed pointer language, some 30 years before either Java or C#. However, a Pascal amalgamated with C would lose that protection by definition. In general, the lower dependence on pointers for basic tasks makes it safer than C in practice.
Line 622 ⟶ 694:
 
== See also ==
* [[C (programming language)|C]], [[C++]]
* [[Pascal (programming language)|Pascal]], [[Object Pascal]], [[Free Pascal]], [[Embarcadero Delphi (programming language)|Delphi]], [[Oxygene (programming language)|Oxygene]]
* [[Component Pascal]]
 
== Notes ==
{{reflist}}
 
== Further reading ==
* [[Kathleen Jensen]] and Niklaus Wirth: ''PASCAL - User Manual and Report.'' Springer-Verlag, 1974, 1985, 1991, {{ISBN|3-540-97649-3}} [https://web.archive.org/web/20050314152247/http://www.cs.inf.ethz.ch/~wirth/books/Pascal/]
* [[Brian Kernighan]], [[Dennis Ritchie]]: ''[[The C Programming Language (book)|The C Programming Language]]''. Also called K&R – the original book on C.
** 1st, Prentice Hall 1978; {{ISBN|0-13-110163-3}}. Pre-ANSI C.
** 2nd, Prentice Hall 1988; {{ISBN|0-13-110362-8}}. ANSI C.
* Niklaus Wirth: [http://portal.acm.org/citation.cfm?id=987330 ''Comment on a note on dynamic arrays in PASCAL''] 37-38, ACM SIGPLAN Notices, Volume 11, Issue 1, January 1976.
* Niklaus Wirth: [http://portal.acm.org/citation.cfm?id=155378 ''Recollections about the Development of Pascal.''] 333-342, ACM SIGPLAN Notices, Volume 28, Issue 3, March 1993.
Line 639 ⟶ 712:
*Alan R. Feuer, Narain H. Gehani: [http://portal.acm.org/citation.cfm?id=356869.356872 ''Comparison of the Programming Languages C and Pascal''] 73-92, ACM Computing Surveys, Volume 14, Issue 1, March 1982.
* ''Comparing and Assessing Programming Languages: Ada, C and Pascal'', Ed. by Alan R. Feuer and Narain Gehani, Prentice Hall, 1984. {{ISBN|0-13-154840-9}}
* Scott Meyers: ''Effective C++'', 2nd Ed., Addison-Wesley, 1998, {{ISBN|0-201-92488-9}}
* Vincent Hayward: [http://portal.acm.org/citation.cfm?id=14950 ''Compared anatomy of the programming languages Pascal and C''] 50-60, ACM SIGPLAN Notices, Volume 21, Issue 5, May 1986.
* [httphttps://wiki.lazarus.freepascal.org/Pascal_for_C_users Pascal for C users] in the FreePascal Compiler Wiki
 
{{Pascal programming language family}}