langlvl

Option Type Default Value #pragma options C C++
-qoption langlvl=ansi* LANGlvl=language x x

Syntax

    -qlanglvl=language 
    LANGLVL=language 

Purpose
Selects the C or C++ language level for the compilation.

Default
The default language level is ansi when you invoke the compiler using the xlC, xlc, or c89 command. The default language level is extended when you invoke the compiler using the cc command.

You can use either of the following preprocessor directives to specify the language level in your C or C++ source program:

    #pragma options langlvl=language
    #pragma langlvl(language)

The pragma directive must appear before any noncommentary lines in the source code.

Notes
For C programs, language is one of:

ansi Compilation conforms to the ANSI C standard.
saal2 Compilation conforms to the SAA C Level 2 CPI language definition, with some exceptions.
saa Compilation conforms to the current SAA C CPI language definition. This is currently SAA C Level 2.
EXTended Provides compatibility with the RT compiler and classic.
classic Allows the compilation of non-ANSI programs, and conforms closely to the K&R level preprocessor.
[no]ucs This option controls whether Unicode characters are allowed in identifiers, string literals and character literals in C++ sources.

The Unicode character set is supported by the C++ standard. This character set contains the full set of letters, digits and other characters used by a wide range of languages, including all North American and Western European languages. Unicode characters can be 16 or 32 bits. The ASCII one-byte characters are a subset of the Unicode character set.

When this option is set to yes, you can insert Unicode characters in your source files either directly or using a notation that is similar to escape sequences. Because many Unicode characters cannot be displayed on the screen or entered from the keyboard, the latter approach is usually preferred. Notation forms for Unicode characters are \uhhhh for 16-bit characters, or \Uhhhhhhhh for 32-bit characters, where h represents a hexadecimal digit. Short identifiers of characters are specified by ISO/IEC 10646.

 

For C++ programs, language is one of:

ansi Compilation conforms to the ANSI C standard for C programs, and the proposed ANSI working paper for C++ programs. The macro __ANSI__ is predefined to be 1. (Same as strict98)
compat366 Compilation conforms to the IBM C and C++ Compilers V 3.6.
extended Compilation conforms is the same as ansi mode, with some differences.
strict98 Compilation conforms to the ANSI C standard for C programs, and the proposed ANSI working paper for C++ programs. The macro __ANSI__ is predefined to be 1. (ansi)
[no]anonstruct This option controls whether anonymous structs and anonymous classes are allowed in your C++ source.

By default, VisualAge C++ allows anonymous structs. This is an extension to the C++ standard and gives behavior that is compatible with the C++ compilers provided by Microsoft Visual C++.

Anonymous structs typically are used in unions, as in the following code fragment:

union U {
   struct {
      int i:16;
      int j:16;
   };
   int k;
} u;
// ...
u.j=3;

When this option is set, you receive a warning if your code declares an anonymous struct. You can suppress the warning with -qsuppress=CPPC0017. When you build with lang(anonymousStructs, no) an anonymous struct is flagged as an error.

Set anonymousStructs to no for compliance with standard C++.

[no]ansifor This option controls whether scope rules defined in the C++ standard apply to names declared in for-init statements.

By default, standard C++ rules are used. For example the following code causes a name lookup error:

{
   //...
   for (int i=1; i<5; i++) {
      cout << i * 2 << endl;
   }
   i = 10;  // error
}

The reason for the error is that i, or any name declared within a for-init-statement, is visible only within the for statement. To correct the error, either declare i outside the loop or set ansiForStatementScopes to no.

Set ansiForStatementScopes to no to allow old language behavior. You may need to do this for code that was developed with other products, such as the compilers provided by earlier versions of VisualAge C++ and predecessor products, and Microsoft Visual C++.

[no]oldfriend This option controls whether friend declarations that name classes without elaborated class names are treated as C++ errors.

By default, VisualAge C++ lets you declare a friend class without elaborating the name of the class with the keyword class. This is an extension to the C++ standard and gives behavior that is compatible with the C++ compilers provided by earlier versions of VisualAge C++ and predecessor products, and Microsoft Visual C++.

For example, the statement below declares the class IFont to be a friend class and is valid when compatFriendDeclarations is set to yes.

friend IFont;

Set compatFriendDeclarations to no for compliance with standard C++. The example declaration above causes a warning unless you modify it to the statement below, or suppress the message with -qsuppress=CPPC0070 option.

friend class IFont;
[no]oldmath This option controls which versions of math function declarations in <math.h> are included when you specify math.h as an included or primary source file.

By default, the new standard math functions are used. Build with lang(compatMath, no) for strict compliance with the C++ standard.

For compatibility with modules that were built with earlier versions of VisualAge C++ and predecessor products you may need to build with lang(compatMath, yes).

[no]oldtempacc This option controls whether access to a copy constructor to create a temporary object is always checked, even if creation of the temporary object is avoided.

By default, VisualAge C++ suppresses the access checking. This is an extension to the C++ standard and gives behavior that is compatible with the C++ compilers provided by VisualAge C++ for OS/2 3.0, VisualAge for C++ for Windows, Version 3.5, and Microsoft Visual C++.

When this option is set to yes, you receive a warning if your code uses the extension, unless you disable the message. Disable the message by building with -qsuppress=CPPC0070 CPPC0306 when the copy constructor is a private member, and -qsuppress=CPPC0307 when the copy constructor is a protected member.

Set -qlanglvl=nooldtempacc for compliance with standard C++. For example, the throw statement in the following code causes an error because the copy constructor is a protected member of class C:

class C {
public:
   C(char *);
protected:
   C(const C&);
};

C foo() {return C("test");}  // returns a copy of a C object 
void f()
{
// catch and throw both make implicit copies of the thrown object
   throw C("error");         // throws a copy of a C object
   const C& r = foo();       // uses the copy of a C object created by foo()
}

The example code above contains three ill formed uses of the copy constructor C(const C&).

[no]oldtmplalign This option specifies the alignment rules implemented in versions of the batch compiler (xlC) prior to Version 5.0. These earlier versions of  the xlC compiler ignore alignment rules specified for nested templates. By default, these alignment rules are not ignored in VisualAge C++ 4.0 or later. For example, given the following template the size of A<char>::B will be 5 with -qlanglvl=nooldtmplalign and 8 with -qlanglvl=oldtmplalign :
template <class T>
struct A {
#pragma options align=packed
 struct B {
  T m;
  int m2;
 };
#pragma options align=reset
};
[no]oldtmplspec This option controls whether template specializations that do not conform to the C++ standard are allowed.

By default, VisualAge C++ allows these old specializations (-qlanglvl=nooldtmplspec). This is an extension to standard C++ and gives behavior that is compatible with the C++ compilers provided by VisualAge C++ for OS/2 3.0, VisualAge for C++ for Windows, Version 3.5, and Microsoft Visual C++.

When -qlanglvl=oldtmplspec is set, you receive a warning if your code uses the extension, unless you suppress the message with -qsuppress=CPPC0080.

For example, you can explicitly specialize the template class ribbon for type char with the following lines:

template<class T> class ribbon { /*...*/};
class ribbon<char> { /*...*/};

Set -qlanglvl=nooldtmplspec for compliance with standard C++. In the example above, the template specialization must be modified to:

template<class T> class ribbon { /*...*/};
template<> class ribbon<char> { /*...*/};
[no]anonunion This option controls what members are allowed in anonymous unions.

When this option is set to yes, anonymous unions can have members of all types that standard C++ allows in non-anonymous unions. For example, non-data members, such as structs, typedefs, and enumerations are allowed.

Member functions, virtual functions, or objects of classes that have non-trivial default constructors, copy constructors, or destructors cannot be members of a union, regardless of the setting of this option.

By default, VisualAge C++ allows non-data members in anonymous unions. This is an extension to standard C++ and gives behavior that is compatible with the C++ compilers provided by previous versions of VisualAge C++ and predecessor products, and Microsoft Visual C++.

When this option is set to yes, you receive a warning if your code uses the extension, unless you suppress the message with -qsuppress=CPPC1608.

Set extendedAnonymousUnions to no for compliance with standard C++.

[no]illptom This option controls what expressions can be used to form pointers to members. VisualAge C++ can accept some forms that are in common use, but do not conform to the C++ standard.

By default, VisualAge C++ allows these forms. This is an extension to standard C++ and gives behavior that is compatible with the C++ compilers provided by earlier versions of VisualAge C++ and predecessor products, and Microsoft Visual C++.

When this option is set to yes, you receive warnings if your code uses the extension, unless you suppress the messages with -qsuppress=CPPC0228; and -qsuppress=CPPC0286.

For example, the following code defines a pointer to a function member, p, and initializes it to the address of C::foo, in the old style:

struct C {
void foo(int);
};

void (C::*p) (int) = C::foo;

Set illformedPointerToMember to no for compliance with the C++ standard. The example code above must be modified to use the & operator.

struct C {
void foo(int);
};

void (C::*p) (int) = &C::foo;
[no]implicitinit This option controls whether VisualAge C++ will accept missing or partially specified types as implicitly specifying int. This is no longer accepted in the standard but may exist in legacy code.

With the option set to no, all types must be fully specified.

With the option set to yes, a function declaration at namespace scope or in a member list will implicitly be declared to return int. Also, any declaration specifier sequence that does not completely specify a type will implicitly specify an integer type. Note that the effect is as if the int specifier were present. This means that the specifier const, by itself, would specify a constant integer.

The following specifiers do not completely specify a type.

  • auto
  • const
  • extern
  • extern "<literal>"
  • inline
  • mutable
  • friend
  • register
  • static
  • typedef
  • virtual
  • volatile
  • platform specific types (for example, _cdecl, __declspec)

Note that any situation where a type is specified is affected by this option. This includes, for example, template and parameter types, exception specifications, types in expressions (eg, casts, dynamic_cast, new), and types for conversion functions.

By default, VisualAge C++ sets -qlanglvl=implicitinit. This is an extension to the C++ standard and gives behavior that is compatible with the C++ compilers provided by earlier versions of VisualAge C++ and predecessor products, and Microsoft Visual C++.

For example, the return type of function MyFunction is int because it was omitted in the following code:

MyFunction()
{
   return 0;
}

Set -qlanglvl=noimplicitint for compliance with standard C++. For example, the function declaration above must be modified to:

int MyFunction()
{
   return 0;
}
[no]newexcp This option determines whether or not the C++ operator new throws an exception.   The standard exception std::bad_alloc can be thrown when the requested memory allocation fails.  This option does not apply to the nothrow versions of the new operator.

The standard implementation of the new operators fully support exceptions.  For compatibility with previous versions of VisualAge C++, these operators return 0 by default.

[no]offsetnonpod This option controls whether the offsetof macro can be applied to classes that are not data-only. C++ programmers often casually call data-only classes "Plain Old Data" (POD) classes.

By default, VisualAge C++ allows offsetof to be used with nonPOD classes. This is an extension to the C++ standard, and gives behavior that is compatible with the C++ compilers provided by VisualAge C++ for OS/2 3.0, VisualAge for C++ for Windows, Version 3.5, and Microsoft Visual C++

When this option is set, you receive a warning if your code uses the extension, unless you suppress the message with -qsuppress=CPPC1281.

Set -qlanglvl=nooffsetnonpod for compliance with standard C++.

Set -qlanglvl=offsetnonpod if your code applies offsetof to a class that contains one of the following:

  • user-declared constructors or destructors
  • user-declared assignment operators
  • private or protected non-static data members
  • base classes
  • virtual functions
  • non-static data members of type pointer to member
  • a struct or union that has non-data members
  • references
[no]olddigraph This option controls whether old-style digraphs are allowed in your C++ source. It applies only when -qdigraph is also sete.

By default, VisualAge C++ supports only the digraphs specified in the C++ standard.

Set -qlanglvl=olddigraph if your code contains at least one of following digraphs:

Digraph Resulting Character

%%
# (pound sign)
%%%%
## (double pound sign, used as the preprocessor macro concatenation operator)

Set -qlanglvl=noolddigraph for compatibility with standard C++ and the extended C++ language level supported by previous versions of VisualAge C++ and predecessor products.

[no]trailenum This option controls whether trailing commas are allowed in enum declarations.

By default, VisualAge C++ allows one or more trailing commas at the end of the enumerator list. This is an extension to the C++ standard, and provides compatibility with Microsoft Visual C++. The following enum declaration uses this extension:

enum grain { wheat, barley, rye,, };

Set -qlanglvl=notrailenum for compliance with standard C++ or with the ANSI language level supported by previous versions of VisualAge C++ and predecessor products.

[no]typedefclass This option provides backwards compatibility with previous versions of VisualAge C++ and predecessor products.

The current C++ standard does not allow a typedef name to be specified where a class name is expected. This option relaxes that restriction. Set -qlangllvl=typedefclass to allow the use of typedef names in base specifiers and constructor initializer lists.

By default, a typedef name cannot be specified where a class name is expected.

[no]ucs This option controls whether Unicode characters are allowed in identifiers, string literals and character literals in C++ sources.

The Unicode character set is supported by the C++ standard. This character set contains the full set of letters, digits and other characters used by a wide range of languages, including all North American and Western European languages. Unicode characters can be 16 or 32 bits. The ASCII one-byte characters are a subset of the Unicode character set.

When -qlanglvl=ucs is set, you can insert Unicode characters in your source files either directly or using a notation that is similar to escape sequences. Because many Unicode characters cannot be displayed on the screen or entered from the keyboard, the latter approach is usually preferred. Notation forms for Unicode characters are \uhhhh for 16-bit characters, or \Uhhhhhhhh for 32-bit characters, where h represents a hexadecimal digit. Short identifiers of characters are specified by ISO/IEC 10646.

The default is -qlanglvl=noucs.

[no]zeroextarray This option controls whether zero-extent arrays are allowed as the last non-static data member in a class definition.

By default, VisualAge C++ allows arrays with zero elements. This is an extension to the C++ standard, and provides compatibility with Microsoft Visual C++. The example declarations below define dimensionless arrays a and b.

struct S1 { char a[0]; };
struct S2 { char b[]; };

Set zeroExtentArrays to no for compliance with standard C++ or with the ANSI language level supported by previous versions of VisualAge C++ and predecessor products.

When this option is set, you receive warnings about zero-extent arrays in your code, unless you suppress the message with -qsuppress=CPPC1607.

 

Exceptions to the ansi mode addressed by classic are as follows:

Tokenization Tokens introduced by macro expansion may be combined with adjacent tokens in some cases. Historically, this was an artifact of the text-based implementations of older preprocessors, and because, in older implementations, the preprocessor was a separate program whose output was passed on to the compiler.

For similar reasons, tokens separated only by a comment may also be combined to form a single token. Here is a summary of how tokenization of a program compiled in classic mode is performed:

  1. At a given point in the source file, the next token is the longest sequence of characters that can possibly form a token. For example, i+++++j is tokenized as i ++ ++ + j even though i ++ + ++ j may have resulted in a correct program.
  2. If the token formed is an identifier and a macro name, the macro is replaced by the text of the tokens specified on its #define directive. Each parameter is replaced by the text of the corresponding argument. Comments are removed from both the arguments and the macro text.
  3. Scanning is resumed at the first step from the point at which the macro was replaced, as if it were part of the original program.
  4. When the entire program has been preprocessed, the result is scanned again by the compiler as in the first step. The second and third steps do not apply here since there will be no macros to replace. Constructs generated by the first three steps that resemble preprocessing directives are not processed as such.

It is in the third and fourth steps that the text of adjacent but previously separate tokens may be combined to form new tokens.

The \ character for line continuation is accepted only in string and character literals and on preprocessing directives.

Constructs such as:

   #if 0
      "unterminated
   #endif
   #define US "Unterminating string
   char *s = US terminated now"

will not generate diagnostic messages, since the first is an unterminated literal in a FALSE block, and the second is completed after macro expansion. However:

   char *s = US;

will generate a diagnostic message since the string literal in US is not completed before the end of the line.

Empty character literals are allowed. The value of the literal is sero.

Preprocessing directives The # token must appear in the first column of the line. The token immediately following # is available for macro expansion. The line can be continued with \ only if the name of the directive and, in the following example, the ( has been seen:
   #define f(a,b) a+b
   f\
   (1,2)      /* accepted */
   #define f(a,b) a+b
   f(\
   1,2)       /* not accepted */

The rules concerning \ apply whether or not the directive is valid. For example,

   #\
   define M 1   /* not allowed */
   #def\
   ine M 1      /* not allowed */
   #define\
   M 1          /* allowed */
   #dfine\
   M 1          /* equivalent to #dfine M 1, even
                   though #dfine is not valid  */

Following are the preprocessor directive differences between classic mode and ansi mode. Directives not listed here behave similarly in both modes.

#ifdef/
#ifndef
When the first token is not an identifier, no diagnostic message is generated, and the condition is FALSE.
#else When there are extra tokens, no diagnostic message is generated.
#endif When there are extra tokens, no diagnostic message is generated.
#include The < and > are separate tokens. The header is formed by combining the spelling of the < and > with the tokens between them. Therefore /* and // are recognized as comments (and are always stripped), and the " and ' do begin literals within the < and >. (Remember that in C programs, C++-style comments // are recognized when -qcpluscmt is specified.)
#line The spelling of all tokens which are not part of the line number form the new file name. These tokens need not be string literals.
#error Not recognized in classic mode.
#define A valid macro parameter list consists of zero or more identifiers each separated by commas. The commas are ignored and the parameter list is constructed as if they were not specified. The parameter names need not be unique. If there is a conflict, the last name specified is recognized.

For an invalid parameter list, a warning is issued. If a macro name is redefined with a new definition, a warning will be issued and the new definition used.

#undef When there are extra tokens, no diagnostic message is generated.
Macro expansion
  • When the number of arguments on a macro invocation does not match the number of parameters, a warning is issued.
  • If the ( token is present after the macro name of a function-like macro, it is treated as too few arguments (as above) and a warning is issued.
  • Parameters are replaced in string literals and character literals.
  • Examples:
       #define M()    1
       #define N(a)   (a)
       #define O(a,b) ((a) + (b))
       M();  /* no error */
       N();  /* empty argument */
       O();  /* empty first argument 
                and too few arguments */
Text Output No text is generated to replace comments.


List of Batch Compiler Options and Their Defaults
Options that Specify Compiler Characteristics
Equivalent Batch Compile-Link and Incremental Build Options