TOP

ASN.1/C++ Compiler Advanced Topics

Applies to: ASN.1/C++ v7.3-7.3.1

ASN.1 Macros

The OSS macro processor is a component of the ASN.1/C++ Compiler that

  • Expands all macro notation.
  • Performs full syntax checking of ASN.1 source files.
  • Produces source listings with all imported items expanded.
  • Generates diagnostic messages.

No preprocessing of the ASN.1 source is required before invoking the OSS macro processor.

Expansion of ASN.1 Macro Notation

A macro assigns a value to the local value reference (VALUE) and returns its ASN.1 type, which is used to determine how the macro should be expanded. So when VALUE has a single assignment in an instance of a macro, the type associated with that value is returned.

A CHOICE type is generated when a macro returns a type that is indeterminate because VALUE has zero or multiple assignments in the macro instance. When VALUE has no assignment, the resulting CHOICE contains every possible type that the macro could return. When VALUE has multiple assignments, the resulting CHOICE contains the types associated with those assignments.

An ANY type is generated when a macro returns a type that is completely indeterminate. For example, an argument assigned to VALUE is present only in a macro's VALUE NOTATION, but the macro is used strictly as a type, with no value specified.

Any macro instance that has an indeterminate returned type is non-standard; its use is discouraged. The compiler tolerates these types of macros only to support those already in existence. A warning message is issued for any use of non-standard macros.

Restrictions on User-Defined Macros

  • When defining one macro by another macro, define the latter first.

    In the following example, OPERATION must be defined before it can be used to define ABSTRACT-OPERATION:

    ABSTRACT-OPERATION MACRO ::= OPERATION
  • The "[" character is not supported in macros as an astring.
  • All macros must be defined before they are used.

    In the example below, A is acceptably defined since no argument is passed to ERROR. C is acceptably defined because ERROR is defined before being referenced by C. On the other hand, B is unacceptably defined since ERROR is referenced before being defined and arguments are passed to it.

    A ::= ERROR
     
    B ::= ERROR PARAMETER BOOLEAN
     
    ERROR MACRO ::= BEGIN
        TYPE NOTATION	::= Parameter
        VALUE NOTATION	::= value(VALUE CHOICE{
           localValue  INTEGER,
           globalValue OBJECT IDENTIFIER})
        Parameter    ::= "PARAMETER" NamedType | empty
        NamedType    ::= identifier type       | type
    END
    
    C ::= ERROR PARAMETER BOOLEAN
  • Macro arguments and values that have no effect on the return type are checked by the compiler for correct usage and have no effect on the compiler output. The compiler treats such parameters and values as formal comments whose meaning is understood only by the user. For example, using the ERROR definition specified above, you can create an instance of ERROR as follows:
     C ::= ERROR PARAMETER BOOLEAN

    NOTE: In the macro definition, the type of the value returned by ERROR is CHOICE {localValue INTEGER, globalValue OBJECT IDENTIFIER}; this type is independent of any parameter passed to ERROR. The compiler syntax-checks the parameters to ensure that whenever the word PARAMETER occurs immediately after ERROR, it is followed by a valid ASN.1 type. These parameters are then forgotten and have no further effect.

Examples of Macro Use

Most of these examples are drawn from the X.208 and X.410 ITU-T Recommendations.

  1. Example of a macro whose returned type is independent of the instance of the type and value notation.

    ERROR macro definition:

    ERROR MACRO ::= BEGIN
       TYPE NOTATION    ::= "PARAMETER" NamedType | empty
       VALUE NOTATION   ::= value(VALUE INTEGER)
       NamedType        ::= identifier type       | type
    END

    Used as follows:

    ErrorRecord ::= SEQUENCE {
       rectype        ERROR PARAMETER VisibleString,
       sector         INTEGER
    }

    Regardless of the parameter passed to the macro, the following definition is always implied because the type returned by the macro is always INTEGER:

    ErrorRecord ::= SEQUENCE {
       rectype        INTEGER,
       sector         INTEGER
    }

  2. Example of another macro whose returned type is independent of the instance of the type and value notation.

    OPERATION macro definition:

    OPERATION MACRO ::= BEGIN
       TYPE NOTATION   ::= "ARGUMENT" NamedType
                  Result Errors      | empty
       VALUE NOTATION  ::= value(VALUE INTEGER)
       Result          ::= empty           | "RESULT" NamedType
       Errors          ::= empty           | "ERRORS" "{"ErrorNames"}"
       NamedType       ::= identifier type | type
       ErrorNames      ::= empty           | IdentifierList
       IdentifierList  ::= identifier      | IdentifierList  "," identifier
    END

    Used as follows:

    cancel OPERATION
       ARGUMENT jobname IA5String
       RESULT   jobCancelled NULL
       ERRORS {jobNotFound, unauthorizedCancel} ::= 1
      
    Message   ::= SEQUENCE {
       invokeID   INTEGER,
            OPERATION,
       argument   ANY
    } 

    Regardless of the parameters passed to the macro, the following code is always generated because the type returned by the macro is always INTEGER:

    lookup INTEGER ::= 1
     
    Message ::= SEQUENCE {
       invokeID   INTEGER,
                  INTEGER,
       argument   ANY
    }

  3. Example of a macro whose returned type is independent of the value notation instance, but is dependent on the type notation instance.

    PAIR macro definition:

    PAIR MACRO ::= BEGIN
    
       TYPE NOTATION ::= 
          "TYPEX" "=" type(LocalType1)
          "TYPEY" "=" type(LocalType2)
       VALUE NOTATION ::=
          "("
          "X" "=" value(LocalValue1 LocalType1)
          ","
          "Y" "=" value(LocalValue2 LocalType2)
          <VALUE SEQUENCE {LocalType1, LocalType2} ::= 
             {LocalValue1, LocalValue2}>
          ")"
    END

    Used as follows:

    AgeAndMarried ::= PAIR
       TYPEX = INTEGER
       TYPEY = BOOLEAN
          
    serena AgeAndMarried ::= (X = 2, Y = FALSE)

    In the generated code, the types are generated based on the macro parameters:

    AgeAndMarried ::= SEQUENCE {
       INTEGER,
       BOOLEAN
       }
    
    serena AgeAndMarried ::= {2, FALSE}

  4. Example of a macro whose returned type depends on the instance of the type and value notation and contains multiple VALUE assignments.

    BIND macro definition:

    BIND MACRO ::= BEGIN
    
       TYPE NOTATION	::= Argument  Result  Error
       VALUE NOTATION	::= Argument-value | Result-value | Error-value
    
       Argument        ::= empty | "ARGUMENT"   Name type(Argument-type)
       Result          ::= empty | "RESULT"     Name type(Result-type)
       Error           ::= empty | "BIND-ERROR" Name type(Error-type)
       Name            ::= empty | identifier
       
       Argument-value	::= empty | "ARGUMENT"
                value(Arg-value Argument-type)
       <VALUE [16] EXPLICIT Argument-type ::= Arg-value>
    
       Result-value::= empty | "RESULT"
                value(Res-value Result-type)
       <VALUE [17] EXPLICIT Result-type   ::= Res-value>
    
       Error-value::= empty | "ERROR"
                value(Err-value Error-type)
       <VALUE [18] EXPLICIT Error-type    ::= Err-value>
    END 

    Used as follows:

    BindA ::= BIND
    BindB ::= BIND RESULT INTEGER
    b BIND ARGUMENT INTEGER ::= ARGUMENT 2

    Warning messages are issued for BindA and BindB, and the following code is generated:

    BindA ::= CHOICE {
    [16] ANY,
    [17] ANY,
    [18] ANY
    }
    
    BindB ::= [17] INTEGER
    
    b [16] INTEGER ::= 2

Backward Compatibility

These compiler -compat flags can be used to restore the behavior of earlier versions of the OSS ASN.1/C++ Tools. Click on a flag name for more information about that flag, or go directly to the ASN.1/C++ Compiler -compat Flags Reference.

Name Description
allowBadDEFAULTValues Silently truncate a size-constrained DEFAULT value that is too long, and issue a warning message.
externIntConst Always generate extern constants for named values, even when they consist of INTEGER and ENUMERATED types.
genericOpenTypes Always use the OssOpen class to represent open types.
oldTypesFromInnerSubtypeWithContentConstraints Instructs the compiler to use the same name specified with the TYPENAME directive for the generated representations of both the base type and the type created after using contents constraints within an inner subtype constraint.
UTF8StringasBMPString Use the OssBMPString class to represent UTF8Strings.
v2.0
v2.0.0
Provides compatibility with version 2.0.0 of the compiler.
v3.0
v3.0.0
Provides compatibility with version 3.0.0 of the compiler.
v3.1
v3.1.0
Provides compatibility with version 3.1.0 of the compiler.
v3.1.1 Provides compatibility with version 3.1.1 of the compiler.
v3.1.2 Provides compatibility with version 3.1.2 of the compiler.
v3.1.3 Provides compatibility with version 3.1.3 of the compiler.
v4.0
v4.0.0
Provides compatibility with version 4.0.0 of the compiler.
v4.0.1 Provides compatibility with version 4.0.1 of the compiler.
v4.0.2 Provides compatibility with version 4.0.2 of the compiler.
v4.1
v4.1.0
Provides compatibility with version 4.1.0 of the compiler.
v4.2
v4.2.0
Provides compatibility with version 4.2.0 of the compiler.
v4.2.1 Provides compatibility with version 4.2.1 of the compiler.
v4.3
v4.3.0
Provides compatibility with version 4.3.0 of the compiler.
v4.3.1 Provides compatibility with version 4.3.1 of the compiler.
v4.3.2 Provides compatibility with version 4.3.2 of the compiler.
v4.3.3 Provides compatibility with version 4.3.3 of the compiler.
v4.3FalseExtendedConstraintEncoding Restores pre-4.3.1 version mishandling of some extensible constraints.
v4.3TableConstraintForExtensibleObjectSets Restores pre-4.3.1 version mishandling of table and component relation constraint violations for extensible object sets.
v4.3reservedWords Restores pre-5.0 version compiler behavior in that "SID" and "small" are not considered reserved words and are not mangled when used as identifiers.
v4.3NoEnumSharing Restores pre-5.0 version compiler behavior when generating common C++ classes for different ASN.1 types having identical C++ representations.
v5.0
v5.0.0
Provides compatibility with version 5.0.0 of the compiler.
v5.0reservedWords Restores pre-6.0 version compiler behavior in that "floor" and "send" are not considered reserved words and are not mangled when used as identifiers.
v6.0
v6.0.0
Provides compatibility with version 6.0.0 of the compiler.
v6.0Sharing Restores pre-6.1 version compiler behavior as to sharing constructed types with recursive definitions.
v6.0valueTruncation Restores pre-6.1 version compiler behavior in that certain values of SEQUENCE OF and SET OF types will not be truncated.
v6.5.0 Provides compatibility with version 6.5.0 of the ASN.1/C++ compiler.
v6.5NamesConflictingWithNicknames Restores pre-6.6 version compiler behavior in that disambiguation of certain generated global names could be skipped when they conflicted with user-defined names specified with the ASN1.Nickname directive.
v6.6.0 Provides compatibility with version 6.6.0 of the ASN.1/C++ compiler.
v6.6DefineNamesForTypesFromInnerWithContentConstraints Instructs the compiler to mangle the global define names with the same values that are generated for similar fields within artificial types created after using contents constraints within an inner subtype constraint.
v6.6PdusForReferencedTypesOfRemovedFields Restores pre-6.7 version compiler behavior in that the compiler no longer treats a named ASN.1 type as a PDU type when the type is referenced only by the fields removed with the ASN1.Remove compiler directive.
v6.7ContentsConstraintsWithRecursiveTypeInsideConstrainedBy Instructs the compiler to not generate PDU classess for types derived from contents constraints that include a user-defined constraint applied to a recursively defined type.
v6.7DataCallback Disables the behavior of DataCallback functions introduced in version 7.0.
v6.7JsonEncodeRestrictedCharStringUsingNonHexForm Prior to release 7.0, the JER encoders/decoders processed TeletexString, T61String, VideotexString, GraphicString, and GeneralString (also ObjectDescriptor) types as JSON strings. This flag restores the old, incorrect behavior.
v7.0.0 Provides compatibility with version 7.0.0 of the ASN.1/C++ compiler.
v7.0.1ImportedWithSuccessorForwardedReferences Instructs the ASN.1 compiler to not report errors or warnings for some unresolved forwarded references imported using WITH SUCCESSORS.
v7.1ArtificialPDUsForRecursivesTypes This standalone flag restores pre-7.1 version compiler behavior and instructs the ASN.1 compiler to create new artificial PDUs for complex recursive types that are defined with CONSTRAINED BY inside parameterized types.
v7.1ContentsConstraintInsideOpenTypeValue Restores pre-7.1 version compiler behavior and instructs the ASN.1 compiler to create a new artificial PDU for a type with contents constraints inside an open type value even when a matching type exists in the information object set specified in the component relation constraint.
v7.1FieldNamesAndGlobalPrefix Instructs the compiler to generate truncated field names that match one of the reserved names when the OSS.DefineName directive is applied to the parent's field marked with OPTIONAL and the -prefix option is specified.
v7.1ForwardedNonParamReferencesImportedWithSuccessors Instructs the ASN.1 compiler to skip some forwarded non-parameterized references that are defined later, are imported using WITH SUCCESSORS, and included inside actual parameters with inner subtype constraints in instances of parameterized types. This behavior might cause warnings in relaxed mode or errors in non-relaxed mode.
v7.2.0
Provides compatibility with version 7.2.0 of the ASN.1 compiler. This flag is equivalent to the following -compat options: v7.2TypesFromConstrainedBy, v7.2PdusForTypesFromDEFAULTInsideInfoObjClass.
v7.2PdusForTypesFromDEFAULTInsideInfoObjClass
Instructs the ASN.1 compiler to disambiguate conflicting PDU names with an extra module name for types used in a DEFAULT syntax applied to VariableTypeFields inside information object classes.
v7.2TypesFromConstrainedBy
Instructs the ASN.1 compiler to generate names that were generated by previous versions of the ASN.1 compiler for types defined in a CONSTRAINED BY syntax.

This documentation applies to release 7.3 and later of the OSS® ASN.1 Tools for C++.

Copyright © 2024 OSS Nokalva, Inc. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without the prior permission of OSS Nokalva, Inc.
Every distributed copy of the OSS® ASN.1 Tools for C++ is associated with a specific license and related unique license number. That license determines, among other things, what functions of the OSS ASN.1 Tools for C++ are available to you.