QuoteThe standard functions Ord and Ptr provide direct control of the address contained in a pointer. Ord returns the address contained in its pointer argument as an Integer, and Ptr converts its Integer argument into a pointer which is compatible with all pointer types.
I didn't say there are no pointers, I said there is no easy-Unions like in C, and in general, in Pascal you need more effort to get the same result.
A Pascal-union-like is called "case inside a record", it makes it possible to give a variable multiple types.
It's not safe
OType = (type1, type2, type3);
OMe = record
case myType: OType of //<-------------- this is a union-like in Pascal
type1: (w1: Integer);
type2: (w2: Integer);
type3: (w3: Integer);
end;
var
O: OMe;
begin
O.myType := Type1;
O.w1 := 1; // this is ok!
O.w2 := 666; //<-------- There is no w2 for Type1, w2 belongs to Type2!
end.
typedef union
{
struct
{
uint32_t w1;
} type1;
struct
{
uint32_t w2;
} type2;
struct
{
uint32_t w3;
} type3;
} OMe_t;
void foo()
{
OMe_t O;
O.type1.w1 = 1;
O.type1.w2 = 666; // <-------- There is no w2 for Type1, w2 belongs to Type2!
}
compiling foo.pas ... done
(no error)compiling foo.c ... failed
foo.c:25: error: 'struct <anonymous>' has no member named 'w2'
Turbo Pascal v7 (embedded inside DoxBox on a Linux machine)Code: [Select]compiling foo.pas ... done
(no error)
C (Gcc on a Linux machine)Code: [Select]compiling foo.c ... failed
foo.c:25: error: 'struct <anonymous>' has no member named 'w2'
Conclusion: unions in C are by - de fact - simpler to check in C than in Pascal.
procedure printOme(O : Ome)
begin
case O.myType of
type1: WriteLn(O.w1);
type2: WriteLn(O.w2);
type3: WriteLn(O.w3)
end
end
var
O: OMe;
begin
O.myType := Type1;
O.w1 := 1;
printOme(O);
O.myType := Type2;
O.w2 := 666;
printOme(O);
end.
void printOme(OMe_t O){
// ?????
printf("%d\n", O.type1.w1);
printf("%d\n", O.type2.w2);
printf("%d\n", O.type3.w3);
}
void foo()
{
OMe_t O;
O.type1.w1 = 1;
primtOme(O);
O.type2.w2 = 666;
primtOme(O);
}
you *can* do this, with extra work, by defining an OType enum and wrapping the union in a struct with an extra myType field. And then in printOme do a switch on the myType field.
you *can* do this, with extra work, by defining an OType enum and wrapping the union in a struct with an extra myType field. And then in printOme do a switch on the myType field.
Of course. That's what you usually do one way or another, unless you love shooting yourself in the foot.
In general, I stand by my assertion that the standardised preprocessor is the only important distinguishing feature between Pascal and C.
outside of unions (for which I agree with you), C still was easier to use for accessing "memory" through structures than Pascal.
outside of unions (for which I agree with you), C still was easier to use for accessing "memory" through structures than Pascal.
Precisely! Plus, easier for the ICE, therefore easier for debugging, which is what I care most about everything.
Ptr converts its Integer argument into a pointer which is compatible with all pointer types.
In general, I stand by my assertion that the standardised preprocessor is the only important distinguishing feature between Pascal and C.
Well, I don't quite agree, but that's a matter of perspective.
I mentioned functions/procedures as parameters, you corrected me saying that they were in the Pascal definition, and I'll believe you. I didn't check. (I admit I never read the official specs of Pascal, contrary to the later Oberon and even - out of curiosity - Modula 3.) I admit I mostly used TP back then, and it didn't implement them. So anyway, let's cross that out.
But there was the matter of separate compilation. I don't think the original spec defined that, but apparently UCSD Pascal was the first defining "units", so that part was long existing too. (And in a better form than just includes.) TP didn't implement this until later versions.
So yeah, not much left missing? IIRC, you could even do conditional compilation in most Pascal compilers with "directives".
Now, outside of unions (for which I agree with you), C still was easier to use for accessing "memory" through structures than Pascal.
I don't think you could, for instance, define the memory location of a record and then access its fields to access particular memory locations as you could do with C. While the equivalent in Pascal was possible, it was not as "elegant" (that may be a matter of taste.) But here again, maybe you have a better memory and command of Pascal, and maybe that was just as easy?
Is “separate compilation units” really considered a feature of the “language”?
I would have thought it orthogonal, the way some assemblers support a linker, and some don’t.
I guess if you want to have the strong typing and range checking of something like pascal, you need an equivalent of “extern” that conveys all that in the absence of full source?
QuoteNow, outside of unions (for which I agree with you), C still was easier to use for accessing "memory" through structures than Pascal.
I don't think you could, for instance, define the memory location of a record and then access its fields to access particular memory locations as you could do with C. While the equivalent in Pascal was possible, it was not as "elegant" (that may be a matter of taste.) But here again, maybe you have a better memory and command of Pascal, and maybe that was just as easy?
Not sure what you mean there. I believe I already showed how to do that in ...
... the only important distinguishing feature between Pascal and C ...
QuoteNow, outside of unions (for which I agree with you), C still was easier to use for accessing "memory" through structures than Pascal.
I don't think you could, for instance, define the memory location of a record and then access its fields to access particular memory locations as you could do with C. While the equivalent in Pascal was possible, it was not as "elegant" (that may be a matter of taste.) But here again, maybe you have a better memory and command of Pascal, and maybe that was just as easy?
Not sure what you mean there. I believe I already showed how to do that in ...
Yes, I corrected that in a later post.
And there's been some kind of "battle" between C-like languages and "wirthian" languages for several decades. (I consider Ada a wirthian language.)
Common points made "against" wirthian languages is that they are seen as more "verbose" and more "rigid". Of course, some will see that as meaning more readable, more maintainable and "safer", while many tend to see this as just plain annoying and counter-productive. The latter seem to be the majority these days, but interestingly, those "arguments" are almost entirely subjective, while the former have at least some objective basis to them.
Whatever is good about C, it's not the syntax, and most especially not the syntax of declarations.
void func()
{
if(asdf == 123)
{
for(int i=0; i<42; i++)
{
if(condition)
break;
}
}
}
#ifdef THING
#if 1==2
void func()
{
...
}
#endif
#endif
Yah, this is annoying.
emacs by default does not indent preprocessor directives -- it forces them to NOT be indented.
This can be changed by adding the following to your .emacs in the c-mode hook:
(c-set-offset (quote cpp-macro) 0 nil)