Integrations (PTC products, 3rd party products and code) > Code integration (Ada, ARINC 653, C, C#, C++, IDL, Java, SQL and VB) > C Code > Generating C Code > Overview of generating C code (C code) > Overview of modeling C code (C code) > Overview of modeling C code (C code) > Attribute mapping for C (C code)
  
Attribute mapping for C (C code)
ACS generates an Attribute globally or within a struct definition:
Globally if the Model or a Package owns the Attribute.
Example code:
// foo.c
static int bar;
Within a struct definition if a Class, Data Type or Signal owns the Attribute.
Example code:
// foo.h
struct foo
{
int bar;
};
You can set up an Attribute to generate a #define. If an Attribute is Read Only with a Default specified but no Type specified, ACS generates the Attribute as a #define.
Example code:
#define Attribute1 17.5
Reverser Notes
When reverse engineering a struct's attributes, the Reverser will reverse engineer an attribute as a Role if all of the following statements are true:
The C attribute's data type can be identified as a struct in the code being reverse engineered.
The C struct that is used as a data type is being reverse engineered.
Reverser cannot match the C attribute to an Attribute in the Model.
If a typed Part (Attribute) has an Association that has not been rolled up to the Part's type, ACS generates a nested struct that is derived from the Part's type. The nested struct defines the Role that is modeled against the Part.
If a Class, Data Type or Signal owns Parts that are connected through an Association, initialization code is generated in the constructor for the Class, Data Type or Signal.
The attribute declaration and initialization is derived from the properties of the Attribute and the tagged values set for Tag Definitions that are applied by the «C Attribute» stereotype.
Classes, Data Types and Signals that Implement Interfaces
For Classes, Data Types and Signals that implement interfaces:
The first member of the generated struct is named 'base' and is typed by the implementing interface.
ACS generates a 'constructor' function, assigns appropriate functions to the function pointer members of the 'base' member, and assigns values to behavior ports.
The Class, Data Type or Signal provides proxies for functions being forwarded to behavior ports that cast the instance parameter to the correct concrete type before making a call.
For Classes, Data Types or Signals containing composite interface-typed non-behavior ports, ACS generates constructor functions that assign functions to the port's function pointer members.
Properties:
For Attributes that are owned by a Class, Data Type or Signal, the Visibility property is ignored. A Class, Data Type or Signal owned Attribute is always generated in the struct, which means it will have public visibility.
Example code:
//foo.h
struct foo
{
int bar;
};
Reverser Notes: When reverse engineering a struct's attributes, the Visibility property of the Attribute is set to Public
For Attributes that are owned by the Model or a Package:
If the Visibility property of the Attribute is set to Public or Protected, the attribute is generated as an extern declaration in the header file with a full definition in the implementation file.
Example code:
// foo.h
extern int bar;
// foo.c
int bar;
If the Visibility property of the Attribute is set to Private, the attribute is declared in the implementation file and marked as static.
Example code:
// foo.c
static int bar;
Reverser Notes: When reverse engineering non-struct scoped attributes, the Visibility property of the Attribute is set is set to Public if the attribute is declared in the header file, or set to Private if the attribute is declared in the implementation file.
For information about how the Behavior property is generated, see the preceding Classes, Data Types and Signals that Implement Interfaces section.
If the Composite property is ignored unless the Multiplicity is user defined with a finite value specified, in which case when set to false (Composite check box cleared on Property Pages), a pointer is used.
Example code:
struct foo
{
int * bar;
};
If the Data Type property is set, ACS generates the value as the attribute's data type, unless there is a value set for the C Function Pointer Return tag definition, in which case that value is used for the attribute's data type.
Example code:
int Attribute3;
static long float Attribute2;
static char* Attribute1;
* 
If no data type is specified, ACS generates int by default. If you want ACS to generate a different default in the absence of a data type for an Attribute, Parameter or Type Definition, change the default value that is specified in the C_Sync.ini file. Tell me more...
Reverser Notes: When reverse engineering an attribute's data type:
If the data type is modeled in the Model or is going to be reverse engineered to the Model, the Attribute's Data Type references the appropriate item.
If the data type is not modeled in the Model and is not going to be reverse engineered to the Model, the Attribute's Data Type is set to the name of the data type (as text).
If the data type is a function pointer, the Attribute's Data Type is not set and instead the C Function Pointer Return and C Function Pointer Parameter tag definitions are used to record the data type.
If a Default Value is set, the attribute is generated as an attribute initializer in the header or implementation file
Example code:
int Attribute3 = 25;
static float Attribute2 = 3.14;
static char* Attribute1 = "foo";
If the Description property has a value, ACS generates the description as a comment on the line before the attribute declaration.
Example code:
/* Comment for attribute foo */
int foo;
If the Multiplicity is user defined with a finite value specified, the user defined value is used as the array specifier.
Example code:
struct foo
{
int bar[4];
};
If the Multiplicity is '0 or More' or '1 or More' a pointer is used, irrespective of whether the Attribute is Composite or not.
Example code:
struct foo
{
int * bar;
};
The Name property is generated as the name of the attribute in the code.
Example code:
int bar;
* 
ACS may modify the attribute name that is added to the code to make it valid for C. You can specify the exact attribute name to add to the code through the CODE_GENERATION_NAME property of an Attribute. Tell me more...
For information about how the Port property is generated, see the preceding Classes, Data Types and Signals that Implement Interfaces section.
If the Read Only property is set to true (Read Only check box selected on Property Pages), the const keyword is used.
Example code:
struct foo
{
const int bar; // Read Only = true
char leaveMeAlone; // Read Only = false
};
const int foobar = 10; // Read Only = true
If the Storage property is set to On Class, the attribute is generated outside of the struct.
Example code:
struct foo
{
char leaveMeAlone; // On Instance
};
int bar; // On Class
The Unique property is ignored.
Tag Definitions:
The following tag definitions are applied to an Attribute by the «C Attribute» stereotype:
If the tagged value of the C Anonymous Item tag definition is set to TRUE, it means that the attribute is used as an anonymous type and is generated with no name. This applies only to Class, Data Type and Signal scoped attributes (bitfields only).
Example code:
// An integer bitfield that is 4 bits wide and has no name.
// often used to pad a structure out.
struct bits
{
int : 4;
};
Reverser Notes: When reverse engineering an attribute that is used as an anonymous type, the Reverser creates an Attribute in Modeler and sets its C Anonymous Item tag definition to TRUE. The name of the Attribute is as follows: unnamed<integer to make unique>
If the tagged value of the C Array Spec tag definition has been set, the value is used as the parameter array, that is, it is generated after the attribute name.
Example code:
structfoo
{
char name[255];
};
#define AgeCount 20
int Ages[AgeCount];
int Multi[5][10];
Reverser Notes: When reverse engineering an initializer or array specification that uses a macro, the C Array Spec tag definition is set to the unpreprocessed text.
If the tagged value of the C Bitfield tag definition has been set, the value is used to generate the bitfield qualifier, that is, the value is preceded with a colon and is generated after the attribute name.
Example code:
int myInt : 4;
int anotherInt : WIDTH;
If the tagged value of the C CV Qualifier tag definition is set to const, volatile or const volatile, the selected keyword is generated before the data type.
Example code:
const int foo;
volatile float pi;
const volatile char cvAttribute;
If the tagged values of the C Function Pointer Parameters and C Function Pointer Return tag definitions have been set, the Attribute declaration is generated as follows:
<C Function Pointer Return> (<C Indirection><derived C Name>)(<C Function Pointer Parameters>);
Example code:
/* void is the C Function Pointer Return value
int and char * are C Function Pointer Parameters values*/
void (* Attribute1)(int, char *);
If the tagged value of the C Indirection tag definition has been set, the value is used as an indirection, that is, the value is generated after the data type and before the attribute name.
Example code:
const int* foo;
volatile float* const pi;
const volatile char* const * cvAttribute;
If the tagged value of the C Storage Class tag definition is set (to auto, register, extern or static) and the Attribute's Storage is On Class, the selected storage class keyword is generated. If the Attribute's Storage is On Instance, the C Storage Class tag definition is ignored. Note that in the context of an Attribute, only the static and extern values of the C Storage Class tag definition should be used.
Example code:
extern float pi;