Chapter Contents

Previous

Next
Source Code Conventions

Language Elements

This section describes standard C constructs for which there are special SAS/C considerations.


Constants


String literals

By default, identically written string constants refer to the same storage location; that is, only one copy of the string is generated by the compiler. The nostringdup compiler option can be used to force a separate copy to be generated for each use of a string literal. However, modifying string constants is not recommended and renders a program non-reentrant.

Strings that are used to initialize char arrays (not char * ) are not actually generated because they are shorthand for a comma-separated list of single-character constants.


Conversions


Pointer conversion

Implicit pointer conversion by assignment is allowed but generates a warning message (which is a diagnostic in the sense of the C Standard) whenever any value other than a pointer of the same type, a pointer to void , the constant 0, or NULL is assigned to a pointer. There is an important reason for the warning. Although many C programs make the implicit assumption that pointers of all types can be stored in int variables or other pointer types and retrieved without difficulty (and this is true for the SAS/C Compiler), the language itself does not guarantee this. On word-addressed machines, for example, such conversions do not always work properly. The warning message provides a gentle (and nonfatal) reminder of this fact. A cast operator can be used to eliminate the warning. The cast then indicates that the conversion is intentional and not the result of improper coding.

A more stringent requirement is enforced for initializers, where the expression to initialize a pointer must evaluate to a pointer, null , or an integral constant 0. Any other value is an error.

When pointers of different types are compared, the operand on the right side of the comparison is converted to the type of the operand on the left side of the comparison; comparison of a pointer and one of the integral types causes a conversion of the integer to the pointer type. Both of these operations are of questionable value unless pointers are being compared for equality or inequality. Note that the result of a relational pointer comparison is undefined (according to ISO/ANSI) if the pointers do not address elements of the same array, structure, or union object.


Declarations


Function prototypes

The standard header files contain prototypes for library functions as specified by the C Standard. Should you want to avoid the use of these prototypes, the preprocessor variable _NOLIBCK enables you to do this. To bypass the prototypes, precede the #include statement for a header file with a #define statement in the following form:

#define _NOLIBCK

You can also define _NOLIBCK from the command line using the define compiler option. Use of _NOLIBCK to suppress library prototypes is strongly discouraged.

Structure and union type names

The compiler accepts unions that have no identifier. See Anonymous unions for more information.

Bitfields

The compiler optionally allows bitfields to have a type other than int , signed int , or unsigned int . See Noninteger bitfields for more information.


Predefined Macro Names

The compiler provides the following predefined macro names required by the C Standard:
__DATE__
__FILE__
__LINE__
__STDC__
__TIME__

These macros are useful for generating diagnostic messages and inline program documentation.
__DATE__ specifies the current date, in the form "Mmm dd yyyy" (for example, Jan 01 1991).
__FILE__ expands to a string constant containing the current filename. The exact form of the name is system-dependent and also depends on the type of the file. In general, the name of the __FILE__ will be a canonicalized version of the source or include filename. If the file is an USS HFS file, __FILE__ contains an absolute pathname, for example, " //HFS:/u/howard/hdrs/protos.h " .
__LINE__ expands to an integer constant that is the relative number of the current source line within the file (primary source file or #include file) that contains it.
__STDC__ specifies the decimal constant 1.
__TIME__ specifies the current time, in the form "hh:mm:ss".

None of the above predefined macros can be undefined with #undef .

The compiler provides the following predefined macro names in addition to the names specified by the ISO/ANSI Standard. The automatic definition of these names can be collectively suppressed by using the undef compiler option. See Compiler Options for more information.

#define DEBUG    1  /* if DEBUG option is used             */
   #define NDEBUG   1  /* if DEBUG option is not used         */
   #define OSVS     1  /* if compiling under TSO or MVS batch */
   #define CMS      1  /* if compiling under CMS              */
   #define _ _I370_ _    1  /* indicates the SAS/C Compiler        */

The #undef preprocessor directive can undefine individually these macro names.

Some predefined macro names indicate certain compiler options. See Preprocessor Options Processing for more information.

The compiler creates two other preprocessor symbols in addition to the option symbols:
__SASC__ is assigned the current release number of SAS/C software. For example, the preprocessor symbol assignment for Release 6.00 is equivalent to the following definition:
#define __SASC__ 600
__COMPILER__ is assigned the current release of SAS/C software as a string. For Release 6.00, this is equivalent to the following definition:
#define __COMPILER__ "SAS/C Version 6.00x "

where x is the product release letter.


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.