Re: [ooc-compiler] Understanding system flags
Brought to you by:
mva
|
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 |