types_def_common.h: Usable types and definitions
1. Motivation
Independent of specific header files this header file contains types and definitons
which are usable and necessary anyway.
It contains also default values for definitions, if they are not specified
in a user’s applstdef_emC.h
, see applstdef_emC_h.html
2. AddrVal_emC: Combination pointer with value
2.1. Macro for type definition
The header file emC/Base/types_def_common.h
defines a macro:
=>source: src_emC/emC/Base/types_def_common.h[tag=STRUCT_AddrVal_emC] /**This macro defines a struct with a pointer to the given type and a integer number. * Usual it can be used to describe exactly an 1-dimensional array. The integer number is the number of elements, * the size in memory is (sizeof(TYPE) * numberOfElements). * This struct should pass with 2 register for call by value or return by value, usual supported by the compiler. */ #define STRUCT_AddrVal_emC(NAME, TYPE) \ struct NAME##_T { TYPE* addr; VALTYPE_AddrVal_emC val; } NAME
With this macro typical small struct
can be defined which contains a memory address
together with a integer value.
The value can often present the size of a memory part or the number of elements of an array.
For example
typedef STRUCT_AddrVal_emC(MyARRAY, float);
defines such a struct
for a user type array as
struct MyARRAY_T { MyArrayType* addr; int32 val; } MyARRAY;
The intension to do so is, often a size or length information to an array reference is stored anywhere other. It is better to bind both parts. It is a simple and effective C approach.
A second, original intension is: Some times the pointer and the value (length) should be returned by value from a function or given as value on call:
MyARRAY myExampleFunction(MyARRAY input) { MyARRAY ret; //instance in stack ret.val = input.val; //example if(ret.val > 333) { } //example return ret; //return the instance per value } void exampleUsage() { myDst = myExampleFunction(mySrc); ....
Compiler can work usual optimizing if the returned value or a calling argument
can be passed by two CPU registers.
On return by value generally the local ret
variable should be copied to a temporary location for return,
and then maybe copied to a used destination of the call.
This copy operations are of course more simple if the values are hold in registers.
Yet the type of the value should depend on the platform and the requirements
of the application (sizes of data).
Often and per default int32
is used, which is proper for 32 bit systems.
But for small memory and less requirements, also 16 bit may be sufficient as special case.
Only in that case you can include in your applstdef_emC.h
,
see applstdef_emC_h.html
//...Part of the user's applstdef_emC.h: #define VALTYPE_AddrVal_emC int16
the given type is used, for example for a small 16 bit processor with 64 kByte address space (hence the address has only 16 bit).
If this definition is missing, a default is valid. This is often the good choice:
=>source: src_emC/emC/Base/types_def_common.h[tag=VALTYPE_AddrVal_emC] /**Default definition int32 as the type for the length or value * in a struct{ addr, val} defined with STRUCT_AddrVal_emC(...). */ #ifndef VALTYPE_AddrVal_emC //possible to define in applstdef_emC.h #define VALTYPE_AddrVal_emC int32 //the default #endif
2.2. Some type definitions
The types_def_common.h
contains
=>source: src_emC/emC/Base/types_def_common.h[tag=int8ARRAY] /**Defines a struct with a byte address and the length. */ typedef STRUCT_AddrVal_emC(int8ARRAY, int8); typedef STRUCT_AddrVal_emC(int16ARRAY, int16); typedef STRUCT_AddrVal_emC(int32ARRAY, int32); typedef STRUCT_AddrVal_emC(int64ARRAY, int64); typedef STRUCT_AddrVal_emC(floatARRAY, float); typedef STRUCT_AddrVal_emC(doubleARRAY, double);
This defines some array types with its length as value.