Thread: [ooc-compiler] Understanding system flags
Brought to you by:
mva
|
From: Frank C. <fj...@th...> - 2006-06-28 14:57:14
|
I'm trying to get a deeper understanding of how system flags affect the
behaviour of types, particularly types equivalent to C strings, structures
and arrays. I need to know this to implement interface modules for C
libraries and Oberon modules manipulating C types such as strings.
SymbolTable.Mod gives the following list of flags:
NO_COPY, ABSTRACT, NO_LENGTH_INFO, NO_DESCRIPTOR, NOT_EXTENSIBLE,
EXTENSIBLE, UNCHECKED_EXCEPTION, CSTRING, NIL_COMPAT, UNION, READ_ONLY,
NO_RETURN, DEPRECATED, OOC_EXTENSIONS, ALIGN1, ALIGN2, ALIGN4, ALIGN8,
VTABLE, NO_TRACED_POINTERS
It would be good to have a description of these flags like the one in OOCRef
for OOC v1. However, the ones I believe are relevant to me are:
NO_LENGTH_INFO, NO_DESCRIPTOR, CSTRING, NIL_COMPAT, UNION
I'm pretty sure I grok NIL_COMPAT and UNION. I'm less sure of the
interaction of NO_LENGTH_INFO, NO_DESCRIPTOR and CSTRING.
For example, how is a C string declared? Module RT0 has these declarations:
TYPE
charPtr1d* = POINTER TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF CHAR;
charPtr2d* = POINTER TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF charPtr1d;
These types represent the arguments passed to a C program in the 'argv'
parameter of the 'main' function. The C declaration varies, but is usually
either:
char * argv[];
or
char ** argv;
On the other hand, Module C declares a C string as:
TYPE
char* = CHAR;
string* = POINTER [CSTRING] TO ARRAY OF char;
The equivalent C declaration would be:
char * whatever
In theory C.string and RT0.charPtr1d should be equivalent but the compiler
understandably treats them as different types. Which one is correct?
--
> When there isn't sufficient virtual memory, the compiler bails out,
> giving an internal error message. When I kill some processes, the
> error goes away.
And what is the compiler supposed to do instead? Go shopping for you
and buy more memory?
-- Falk Hueffner, on the GNU C++ compiler
|
|
From: Michael v. A. <mic...@gm...> - 2006-06-28 18:30:53
|
Hi Frank, it has been some time since I had to do interfacing to C libraries myself. I had to do some reading myself to recall this stuff, so bear with me if my first attempt at an explanation falls short... On 28/06/06, Frank Copeland <fj...@th...> wrote: > > I'm trying to get a deeper understanding of how system flags affect the > behaviour of types, particularly types equivalent to C strings, structures > and arrays. I need to know this to implement interface modules for C > libraries and Oberon modules manipulating C types such as strings. > > SymbolTable.Mod gives the following list of flags: > > NO_COPY, ABSTRACT, NO_LENGTH_INFO, NO_DESCRIPTOR, NOT_EXTENSIBLE, > EXTENSIBLE, UNCHECKED_EXCEPTION, CSTRING, NIL_COMPAT, UNION, READ_ONLY, > NO_RETURN, DEPRECATED, OOC_EXTENSIONS, ALIGN1, ALIGN2, ALIGN4, ALIGN8, > VTABLE, NO_TRACED_POINTERS > > It would be good to have a description of these flags like the one in > OOCRef > for OOC v1. However, the ones I believe are relevant to me are: > > NO_LENGTH_INFO, NO_DESCRIPTOR, CSTRING, NIL_COMPAT, UNION > > I'm pretty sure I grok NIL_COMPAT and UNION. I'm less sure of the > interaction of NO_LENGTH_INFO, NO_DESCRIPTOR and CSTRING. Both NO_LENGTH_INFO and NO_DESCRIPTOR denote the absence of certain run-time type information normally associated with Oberon types. These flags are implicity set for types defined in INTERFACE modules, but must be explicitly set in FOREIGN modules. CSTRING relaxes the assignment rules. When set for a pointer type, compatible _array_ values can be assigned to the variable. In this case, the pointer variable takes the address of the right hand side of the assignment. For example, how is a C string declared? Module RT0 has these declarations: > > TYPE > charPtr1d* = POINTER TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF CHAR; > charPtr2d* = POINTER TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF > charPtr1d; > > These types represent the arguments passed to a C program in the 'argv' > parameter of the 'main' function. The C declaration varies, but is usually > either: > > char * argv[]; > > or > > char ** argv; > > On the other hand, Module C declares a C string as: > > TYPE > char* = CHAR; > string* = POINTER [CSTRING] TO ARRAY OF char; > > The equivalent C declaration would be: > > char * whatever > > In theory C.string and RT0.charPtr1d should be equivalent but the compiler > understandably treats them as different types. Which one is correct? The definition from C is in full string* = POINTER [NO_LENGTH_INFO, NO_DESCRIPTOR, CSTRING] TO ARRAY OF char; due to the implicit flags induced by INTERFACE. Both string and charPtr1d describe the same type structure in memory (by means of the NO_* flags), and are in this sense both correct. They differ if they appear on the left hand side of an assignment, or as a formal parameter. The `string' type allows to pass string constants and character arrays to the pointer, while `charPtr1d' does not. Which to choose is basically a decision how much C semantics you prefer in your programs. 'string' is more convenient in formal parameter lists, simply because SYSTEM.VAL(P,SYSTEM.ADR(a)) is so cumbersome. -- mva |
|
From: Frank C. <fj...@th...> - 2006-07-01 11:45:32
|
> On 28/06/06, *Frank Copeland* <fj...@th... > <mailto:fj...@th...>> wrote: [...] > For example, how is a C string declared? Module RT0 has these > declarations: > > TYPE > charPtr1d* = POINTER TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF > CHAR; > charPtr2d* = POINTER TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF > charPtr1d; [...] > On the other hand, Module C declares a C string as: > > TYPE > char* = CHAR; > string* = POINTER [CSTRING] TO ARRAY OF char; Michael van Acken wrote: > The definition from C is in full > > string* = POINTER [NO_LENGTH_INFO, NO_DESCRIPTOR, CSTRING] TO ARRAY OF > char; > > due to the implicit flags induced by INTERFACE. Does it matter whether the flags are attached to the POINTER part of the declaration or the ARRAY part? Would: string* = POINTER [CSTRING] TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF char; be an equivalent declaration? > Both string and > charPtr1d describe the > same type structure in memory (by means of the NO_* flags), and are in > this sense both > correct. They differ if they appear on the left hand side of an > assignment, or as a for ||mal > parameter. The `string' type allows to pass string constants and > character arrays to the > pointer, while `charPtr1d' does not. > > Which to choose is basically a decision how much C semantics you prefer > in your > programs. 'string' is more convenient in formal parameter lists, simply > because > |SYSTEM.VAL(P,SYSTEM.ADR(a)) is so cumbersome. I want ultimately to hide the C semantics behind a module interface but need to access them in full to implement it. Thanks for the clarification. -- Frank |
|
From: Michael v. A. <mic...@gm...> - 2006-07-03 05:49:28
|
On 01/07/06, Frank Copeland <fj...@th...> wrote: > > > On 28/06/06, *Frank Copeland* <fj...@th... > > <mailto:fj...@th...>> wrote: > [...] > > On the other hand, Module C declares a C string as: > > > > TYPE > > char* = CHAR; > > string* = POINTER [CSTRING] TO ARRAY OF char; > > Michael van Acken wrote: > > > The definition from C is in full > > > > string* = POINTER [NO_LENGTH_INFO, NO_DESCRIPTOR, CSTRING] TO ARRAY OF > > char; > > > > due to the implicit flags induced by INTERFACE. > > Does it matter whether the flags are attached to the POINTER part of the > declaration or the ARRAY part? Would: > > string* = POINTER [CSTRING] TO ARRAY [NO_LENGTH_INFO, NO_DESCRIPTOR] OF > char; > > be an equivalent declaration? My mistake. I have not checked with the actual implementation, but the NO_* flags are almost certainly attached to the ARRAY. Your declaration is the correct one. -- mva |