Chapter Contents |
Previous |
Next |
SAS/C C++ Translator Changes in Release 7.50 |
The following updates apply to SAS/C C++ Development System User's Guide.
Updates to Introduction to the SAS/C C++ Development System |
The following updates apply to Chapter 1, "Introduction to the
SAS/C C++ Development System."
Make the following changes to the section titled "C++ Language Definition:"
NOBITFIELD
option to handle bitfield widths
as specified in the C++ standard.
Friend names are injected into the enclosing namespace
unless the NOFRIENDINJECT
option is specified.
Make the following changes to the section titled "Improved Conformance with the C++ Standard."
NOBITFIELD
option can
be used to enforce C++ standard rules about bitfield widths.
Note: The C++ translator injects the names from friend
declarations into the
containing namespace when defining a class unless the NOFRIENDINJECT
option is specified. Friend declarations are always visible
to name lookups that are argument dependent when the arguments use matching
namespaces and classes.
Make the following changes to the section titled "Environmental Elements:"
Replace the table labeled "Integral Type Sizes" with the following table:
Type | Length in Bytes | Range |
---|---|---|
bool |
1 | false, true |
char |
1 | 0 to 255 (EBCDIC character set) |
signed char |
1 | -128 to 127 |
short |
2 | -32768 to 32767 |
unsigned short |
2 | 0 to 65535 |
int |
4 | -2147483648 to 2147483647 |
unsigned int |
4 | 0 to 4294967295 |
long (NOHUGEPTRS) |
4 | -2147483648 to 2147483647 |
unsigned long (NOHUGEPTRS) |
4 | 0 to 4294967295 |
long (HUGEPTRS) |
8 | -9223372038854775808 to 9223372036854775807 |
unsigned long (HUGEPTRS) |
8 | 0 to 18446744073709551615 |
long long |
8 | -9223372038854775808 to 9223372036854775807 |
unsigned long long |
8 | 0 to 18446744073709551615 |
wchar_t |
2 | 0 to 65535 |
Replace the table labeled "Float and Double Type Sizes" with the following table:
Type | Length in Bytes | Range |
---|---|---|
float |
4 | +/-5.4E-70 to +/-7.2E75 (_ _hexfmt)+/-1.4E-45 to +/-3.4E38 (_ _binfmt) |
double |
8 | +/-5.4E-70 to +/-7.2E75 (_ _hexfmt)+/-4.9E-324 to +/-1.8E308 (_ _binfmt) |
long double |
8 | +/-5.4E-70 to +/-7.2E75 (_ _hexfmt)+/-4.9E-324 to +/-1.8E308 (_ _binfmt) |
In the section titled "Language Elements," make the following changes to the section titled "Predefined Constants:"
c_plusplus
from the list of predefined constants and the list of macro descriptions.
The translator also defines the preprocessor option symbols described in the SAS/C Compiler and Library User's Guide in Chapter 6, "Compiler Options," in the section titled "Preprocessor Symbols."
Make the following changes in the section titled "Language Extensions:"
long long
values in #if
expressions."
_ _binfmt _ _huge _ _norent _ _far _ _multireturn _ _rent _ _hexfmt _ _near _ _setjmp
Note: The translator
also supports the C99 hexadecimal floating point format.
Decimal constants like 4000000000 that are too large to represent as signed long
, and that do not have a
U
or u
suffix, are treated as unsigned long
. This is the same treatment that these large
decimal constants would receive under the C89 rule. Octal, hexadecimal, and
explicitly unsigned constants are not affected.
Add the following sections to the "Language Extensions" section after the subsection titled "C++ iostream Library Constructors:"
#pragma
options copts(...)
directive, in a manner comparable
to the C compiler. The following is a sample directive:
#pragma options copts(sname(ABC123))Most of the options that the C compiler allows to be changed through
#pragma
options can also be specified for C++. Options like PPIX
that are not supported for C++ compilations are also not supported through #pragma
options in C++.
0x<hexdecimal-digits>.<hexdecimal digits>P<binary exponent><suffixes>For more details, see the section titled "Specifying floating-point constants in hexadecimal" in Chapter 2, "Source Code Conventions," of the SAS/C Compiler and Library User's Guide .
B
or H
to explicit specify that a floating point
constant is in _ _binfmt
or _ _hexfmt
respectively. These suffixes can be used
with all the floating point constant formats and follow any F
or L
suffixes. Note suffixes
must be preceded by a period when they are used with the SAS/C hexadecimal
format. For example 0.x4110.FH
is a valid _ _hexfmt
constant.
Make the following changes to the section titled "C++ specific behaviors" In the section titled "Implementation-Defined Behavior:"
There are
three accepted linkage strings: C
, C++
, and OS
. C
linkage for functions
means that type information is not
encoded in the function's identifier. C
linkage
does not affect the linkage for non-functions. OS
is like C
except that _ _ibmos
is implicitly applied to non-member function declarators.
Remember that the linkage for main is always C
.
typeid
expression is const std::type_info
.
reinterpret_cast
. Otherwise for valid casts the reinterpret_cast
operator has semantics matching the cast
operator in C code. The reinterpret_cast
operator
does not perform adjustments based on class inheritance.
signed
int
if all the enumeration constant values fit. Otherwise
the underlying type is unsigned int
.
char
bitfields are unsigned.
A bool
bitfield has the same layout as an
unsigned char
field. A wchar_t
bitfield has the same layout as an unsigned
short
field. An enumeration
bitfield has the same layout as a bitfield of the underlying type of the enumeration
except that the field will be unsigned if all declared enumeration constant
values are non-negative.
rvalue
to
a compatible const
reference, the reference
is bound directly to the rvalue
object if the
class has a nontrivial destructor or nontrivial copy constructor. Otherwise
the rvalue
is copied to a temporary and the
reference is bound to the temporary. The temporary copy, however, can be
elided by the rules in section 12.8 of the C++ standard.
std::terminate()
.
Add the following item to the list in the section titled "Anachronisms:"
NOFRIENDINJECT
option.
Updates to Translator Options |
The following updates apply to Chapter 3, "Translator Options."
In Chapter 3, "Translator Options," in the section titled, "Option
Summary," replace the entries for asciiout
, INLIne
, and tronly
in the table
labeled, "Translator Options," with the following entries.
Option Name | Default | USS | Environment | Affects Process |
---|---|---|---|---|
ASCiiout |
NOASCiiout |
-Kasciiout |
all | T,C |
INLIne |
see description | -Kinline |
all | G |
TROnly |
see description | -Ktronly |
all | T |
Add the following entries to the table labeled, "Translator Options."
Option Name | Default | USS | Environment | Affects Process |
---|---|---|---|---|
ARChlevel |
see description | -Karchlevel=let |
all | T,C |
ARMode |
NOARMode |
-Karmode |
all | T,C |
BFp |
NOBFp |
-Kbfp |
all | T,C |
FRIendinject |
NOFRIendinject |
-Kfriendinject |
all | T |
HUgeptrs |
NOHUgeptrs |
-Khugeptrs |
all | T,C |
OPTIOns |
OPTIOns |
-Koptions |
all | L |
TErm |
see description | -Kterm |
all | M |
Make the following changes to the list of option descriptions in the section titled "Option Descriptions:"
tronly
with the following information:
tronly
list-entry term
to the following:
tronly
(-Ktronly
)
under USS
tronly
description:
Under USS, the following command sends the tronly
output to hello..c
:
sascc370 -v -c -Ktronly hello.cpp
Note the two periods (..) between
the file's basename and extension. This is to prevent accidental overwriting
of a hello.c
source file. Also note that you
have to specify the -c
option to prevent the binder
from being called.
The following example specifies an output filename for
the -Ktronly
option:
sascc370 -v -c -Ktronly=test.c hello.cpp
bitfield
option description that reads:
This option cannot be negated.
with text that reads:
By default the SAS/C rules are used for the interpretation of bitfield
widths. The NOBITFIELD
option can be used
to enforce the bitfield rules from the C++ standard instead of applying the
SAS/C bitfield rules. With NOBITFIELD
option,
bitfield widths that are larger than the field unit type have a different
layout. For example an unsigned char bitfield
that is 12 bits wide has 12 data bits by the SAS/C rules. With the NOBITFIELD
option there are 8 data bits, the width of an unsigned
char, and 4 padding bits.
inline
option with text that reads:
controls inlining in the C++ translator as well as the optimizer. The
translator performs inlining by default unless the DEBUG
option is used. The use of the DEBUG
option
forces NOINLINE
. The translator can inline
functions that require exception handling support, unlike GO
. Translator inlining can be explicitly disabled with the NOINLINE
option.
archlevel
(-Karchlevel=let
under USS)ARCHLEVEL(D)
if the HUGEPTRS
option is specified and ARCHLEVEL(C)
if the BFP
option
is specified. Otherwise the default is unspecfied and no new architecture
features are assumed.
armode
(-Karmode
under USSbfp
(-Kbfp
under USS)BFP
option implies the ARCHLEVEL(C)
option.
friendinject
(-Kfriendinject
under USS)FRIENDINJECT
option is the default for compatility with older
code; however, this default may change in a future release.
hugeptrs
(-Khugeptrs
under USS)hugeptrs
is specified,
the default pointer type is _ _huge
,
and the size of signed
and unsigned long
data is 8 bytes. Note that the hugeptrs
option implies the
ARCHLEVEL(D)
option.
options
(-Koptions
under USS)term
(-Kterm
under USS)stderr
.
The messages appear in addition to the messages in the listing file, if any.
By default the term
option is enabled
only when no listing is created.
Updates to Standard Libraries |
The following updates apply to Chapter 4, "Standard Libraries."
Unless overridden in a derived class this string is std::exception
or derived
class
.
to the following:
Unless overridden in a derived class this string is "std::exception
or derived
class
".
Also change the prototype of xtrace
under "STATIC
MEMBER FUNCTIONS (SAS/C EXTENSION)" to the following:
static void xtrace( _ _remote void (*writer)(const _ _near char *line) = 0 );
Unless overridden in a derived class, this string is as follows:
std::bad_exception
or
derived class
to the following:
Unless overridden in a derived class, this function returns the string "std::bad_exception
or derived
class
".
In the section titled "class std::bad_alloc," under "VIRTUAL MEMBER FUNCTIONS," change the text that reads:
Unless overridden in a derived class this string is std::bad_alloc
or derived
class
.
to the following:
Unless overridden in a derived class this string is "std::bad_alloc
or derived
class
".
const char* name() const;
to read:
The function calls a library allocator to allocate working storage.
Unless overridden in a derived class this string is std::bad_cast
or derived
class
.
to the following:
Unless overridden in a derived class this string is "std::bad_cast
or derived
class
".
Unless overridden in a derived class this string is std::bad_typeid
or derived
class
.
to the following:
Unless overridden in a derived class this string is "std::bad_typeid
or derived
class
".
Unless overridden in a derived class this string is std::_ _non_rtti
or
derived class
.
to the following:
Unless overridden in a derived class this string is
"std::_ _non_rtti
or derived class
".
In the section titled "C++ Complex Library," add the following note after the first paragraph.
Note: This library performs all computations
using _ _hexfmt
floating-point and expects
its operands to be in this format.
Update "I/O Class Descriptions" with the following changes:
Note: These classes are not supported with
the HUGEPTRS
option.
#include <fstream.h> class ifstream : public istream { public: ifstream(); ifstream(const char _ _near *name, int mode = ios::in, const char _ _near *amparms = "", const char _ _near *am = ""); virtual ~ifstream(); void open(const char _ _near *name, int mode = ios::in, const char _ _near *amparms = "", const char _ _near *am = ""); void close(); void setbuf(char *p, int len); filebuf* rdbuf(); }; class ofstream : public ostream { public: ofstream(); ofstream(const char _ _near *name, int mode = ios::out, const char _ _near *amparms = "", const char _ _near *am = ""); virtual ~ofstream(); void open(const char _ _near *name, int mode = ios::out, const char _ _near *amparms = "", const char _ _near *am = ""); void close(); void setbuf(char *p, int len); filebuf* rdbuf(); }; class fstream : public iostream { public: fstream(); fstream(const char _ _near *name, int mode, const char _ _near *amparms = "", const char _ _near *am = ""); virtual ~fstream(); void open(const char _ _near *name, int mode, const char _ _near *amparms = "", const char _ _near *am = ""); void close(); void setbuf(char *p, int len); filebuf* rdbuf(); };
In CONSTRUCTORS, replace the second group of prototypes for constructors with arguments with the following code:
ifstream::ifstream(const char _ _near *name, int mode = ios::in, const char _ _near *amparms = " ", const char _ _near *am = " ") ofstream::ofstream(const char _ _near *name, int mode = ios::out, const char _ _near *amparms = "", const char _ _near *am = "") fstream::fstream(const char _ _near *name, int mode, const char _ _near *amparms = "", const char _ _near *am = "")
In MEMBER FUNCTIONS replace the group of prototypes for open functions with the following code:
void ifstream::open(const char _ _near *name, int mode = ios::in, const char _ _near *amparms = " ", const char _ _near *am = " ") void ofstream::open(const char _ _near *name, int mode = ios::out, const char _ _near *amparms = " ", const char _ _near *am = " ") void fstream::open(const char _ _near *name, int mode, const char _ _near *amparms = "", const char _ _near *am = "")
#include
<iostream.h>
, add the following two lines of code:
typedef unsigned long _ulong; // for NOHUGEPTRS compilations typedef unsigned int _ulong; // for HUGEPTRS compilations
static unsigned long ios::bitalloc()
to
static
_ulong ios::bitalloc()
unsigned long
(unsigned int
with the HUGEPTRS
option) with a single, previously unallocated, bit set. This
allows you to create additional format flags. This function returns 0 if there
are no more bits available. Once the bit is allocated, you can set it and
clear it using the flags()
, setf()
, and unsetf()
functions.
#include <iostream.h> typedef unsigned long _ulong; // for NOHUGEPTRS compilations typedef unsigned int _ulong; // for HUGEPTRS compilations class ios { public: /* See the class ios, enum io_state, enum open_mode, and enum seek_dir descriptions for more definitions. */ enum {skipws, left, right, internal, dec, oct, hex, showbase, showpoint, uppercase, showpos, scientific, fixed, unitbuf, stdio }; static const _ulong basefield; static const _ulong adjustfield; static const _ulong floatfield; _ulong flags(); _ulong flags(_ulong f); _ulong setf(_ulong mask); _ulong setf(_ulong setbits, _ulong mask); _ulong unsetf(_ulong mask); };
The following functions can be used to switch format flags on and off:
_ulong ios::flags()
unsigned long
(unsigned int
with HUGEPTRS
) representing the current format flags.
_ulong ios::flags
(_ulong f)
f
and returns an unsigned long
(unsigned int
with HUGEPTRS
) representing the previous flag values.
_ulong ios::setf (_ulong
mask)
mask
and returns an unsigned long
(unsigned int
with HUGEPTRS
) representing the previous values of those flags. You can
accomplish the same task by using the parameterized manipulator, setiosflags
.
_ulong ios::setf (_ulong setbits, _ulong
mask)
setbits
and
returns an unsigned long
(unsigned
int
with HUGEPTRS
) representing
the previous values of the bits specified by mask. The EXAMPLES section provides
an example of using this function.
Using setf(0, mask)
clears all the bits
specified by field
. You can accomplish the
same task by using the parameterized manipulator resetiosflags
.
_ulong ios::unsetf (_ulong
mask)
mask
and returns an unsigned long
(unsigned int
with HUGEPTRS
) representing the previous flag
values.
istream&
operator >>(unsigned long& l);
, add the following two
lines of code:
istream& operator >>(long long& ll); istream& operator >>(unsigned long long& ll);
istream& operator >>(float& f); istream& operator >>(double& d); istream& operator >>(long double& ld);
to
istream& operator >>(_ _hexfmt float& f); istream& operator >>(_ _hexfmt double& d); istream& operator >>(_ _hexfmt long double& ld); istream& operator >>(_ _binfmt float& f); // if ARCHLEVEL>=C istream& operator >>(_ _binfmt double& d); // if ARCHLEVEL>=C istream& operator >>(_ _binfmt long double& ld); // if ARCHLEVEL>=C
istream& istream::operator >>(unsigned long& l)
,
add the following two lines of code:
stream& istream::operator >>(long long& l) istream& istream::operator >>(unsigned long long& l)
istream& istream::operator >>(float& f) istream& istream::operator >>(double& d) istream& istream::operator >>(long double& ld)
to
istream& istream::operator >>(_ _hexfmt float& f) istream& istream::operator >>(_ _hexfmt double& d) istream& istream::operator >>(_ _hexfmt long double& ld) istream& istream::operator >>(_ _binfmt float& f) istream& istream::operator >>(_ _binfmt double& d) istream& istream::operator >>(_ _binfmt long double& ld)
Note: The _ _binfmt
input functions are only available if the ARCHLEVEL
option is C
or greater.
ostream& operator <<(unsigned long l);
,
add the following two lines of code:
ostream& operator <<(long long ll); ostream& operator <<(unsigned long long ll);
ostream& operator <<(float f); ostream& operator <<(double d);
to
ostream& operator <<(_ _hexfmt float f); ostream& operator <<(_ _hexfmt double d); ostream& operator <<(_ _hexfmt long double d); ostream& operator <<(_ _binfmt float f); // if ARCHLEVEL>=C ostream& operator <<(_ _binfmt double d); // if ARCHLEVEL>=C ostream& operator <<(_ _binfmt long double d); // if ARCHLEVEL>=C
ostream& ostream::operator <<(unsigned long l)
add the following two lines of code:
ostream& ostream::operator <<(long long ll) ostream& ostream::operator <<(unsigned long long ll)
ostream& ostream::operator <<(float f) ostream& ostream::operator << (double d)
to
ostream& ostream::operator <<(_ _hexfmt float f) ostream& ostream::operator <<(_ _hexfmt double d) ostream& ostream::operator <<(_ _hexfmt long double d) ostream& ostream::operator <<(_ _binfmt float f) ostream& ostream::operator <<(_ _binfmt double d) ostream& ostream::operator <<(_ _binfmt long double d)
Note: The _ _binfmt
output functions are only available if the ARCHLEVEL
option is C
or greater.
#include <stdiostream.h> class stdiostream : public iostream { public: stdiostream(_ _near FILE *file); stdiobuf* rdbuf(); };
stdiostream::stdiostream(FILE *file)
with the following prototype:
stdiostream::stdiostream(_ _near FILE *file)
stdiofile()
from the MEMBER FUNCTIONS section.
Note: Although streampos
supports 64-bit integer
offsets when the HUGEPTRS
option, only offsets
in the 32-bit range are supported by the I/O library.
Update "Buffer Class Descriptions" with the following changes:
Note: None of the classes defined
in <bsamstr.h>
are supported by the HUGEPTRS
option.
open()
in the SYNOPSIS with the following code:
filebuf* open(const char _ _near *name, int mode, const char _ _near *amparms = "", const char _ _near *am = "");
filebuf::open
in the NONVIRTUAL MEMBER FUNCTIONS section with the following code:
filebuf* filebuf::open(const char _ _near *name, int mode, const char _ _near *amparms = "", const char _ _near *am = "")
virtual streambuf*
filebuf::setbuf
Note: In Release
7.50, the value of len
must be less or equal
to 2^32-1 bytes.
#include <stdiostream.h > class stdiobuf : public streambuf { public: stdiobuf(_ _near FILE *file); virtual ~stdiobuf( ); int is_open( ); _ _near FILE* stdiofile( ); streampos seekoff(streamoff offset, seek_dir place, int mode = ios::in|ios::out); streampos seekpos(streampos pos, int mode = ios::in|ios::out); virtual int sync(); };
stdiobuf::stdiobuf(FILE *file)
to
stdiobuf::stdiobuf(_ _near FILE *file)
FILE* stdiofile()
to
_ _near FILE* stdiofile)
Updates to Header Files, Classes, and Functions |
The following updates apply to Appendix 2, "Header Files, Classes,
and Functions."
In the section titled "Stream Classes," in the table labeled "Header
Files, Classes, and Functions for Streams," in the entry for stdiostream.h
, delete the term stdiofile()
from the Functions
column.
Updates to Templates |
The following updates apply to Appendix 3, "Templates."
Make the following changes to the section titled "Template Paremeters:"
data member pointers
to
data or function member pointers
Nontype template parameters can use previously declared template parameters in their declaration type. For example,
template <class T, T* someObject> class C { }; int p; C <int, &p> c; template <int I, int (*pArray[I])> class C2; // ok template <int I, int (*pBigArray[I*100])> // ok class C3;
In the section titled "Template Arguments," change the last list item to read:
&class_name::member
Make the following changes In the section titled "Template Declarations and Definitions," in the section titled "Declaration Rules."
Note: Template friend declarations
of template class members are not supported in this release of the SAS/C C++
Development System.
However, friend template declarations may not be definitions.
to
However, friend template class declarations may not be definitions.
Note: Beginning with Release
6.50, template parameters may not have default arguments.
In the section titled "Function Templates," in the section titled "Deducing Arguments," add the following item at the end of the bulleted list:
derived to base conversions
When the parameter type is a template ID or pointer to a template ID then deduction will consider derived-to-base conversions to match the template ID.
Updates to Interpreting C++ Demangled Names |
The following updates apply to Appendix 5, "Interpreting C++ Demangled Names."
In the section titled "Special Conventions Used in Demangled Names," add the following entries to the table labeled "Keywords and Their Abbreviations."
Keyword | Abbreviation |
---|---|
_ _binfmt |
_B |
_ _far |
_F |
_ _huge |
_H |
New Appendix on ARMODE, HUGEPTRS, and Pointer Kinds |
After Appendix 5, "Interpreting C++ Demangled Names," add a new appendix titled "ARMODE, HUGEPOINTERS, and Pointer Kinds" that contains the following information.
The C++ translator supports the HUGEPTRS
and ARMODE
options as well as the _ _near
, _ _far
,
and _ _huge
keywords in pointer and
reference declarations. This appendix describes some of the special considerations
for use of these SAS/C features with C++.
Pointer operations generally behave the same way with the C++ translator that they do with the C compiler. However the C++ translator is more restrictive about implicit pointer conversions in order to facilitate overloading and avoid unsafe conversions. Far and huge pointers cannot be converted to a different pointer kind without an explicit cast. As a special case pointers to strings and simple pointer expressions that can be determined at compile time to address auto, formal, static, or external objects can be implictly converted to near pointers.
References can be _ _near
, _ _far
, or _ _huge
.
By default object references are _ _near
unless HUGEPTRS
is specified, in which case
they are _ _huge
. Dereferencing a _ _huge
reference requires the HUGEPTRS
option.
Dereferencing a _ _far
reference requires ARMODE
. With the HUGEPTRS
option, only huge const references can bind to non-lvalues.
C++ specific pointer
operations have their own restrictions. Conversion
of a far pointer to a base class pointer requires the ARMODE
option. Conversion of a huge pointer to a base class pointer
requires the HUGEPTRS
option. Applying dynamic_cast
to far pointers or references requires the ARMODE
option. Similarly, applying dynamic_cast
to huge pointers or references requires the HUGEPTRS
option.
Class object layout
does not depend on the HUGEPTRS
or ARMODE
option except for differences due
to user nonstatic data members. However a nonstatic member function always
has a default sized this
pointer. That is,
in a HUGEPTRS
compilation the this
parameter will be a 64-bit huge pointer instead of a
32 bit near pointer. ARMODE
does not affect
the this
pointer type. Virtual function calls
to objects created in a different mode will cause unexpected results. Mixing HUGEPTRS
and non-HUGEPTRS
code
is not generally recommended.
The new
operator always returns a default
sized pointer. The return type for an operator new function and the first
argument for a delete function must be a default void pointer. The leftmost
array size in an array allocation type can be a 64-bit quantity when HUGEPTRS
is specified.
Enumeration constants and array sizes are limited to 32 bit values, except for the leftmost array size in a declarator for a new expression.
The std::bad_exception
object thrown
by the C++ library when a mismatched exception is encountered expects virtual
function calls with 64-bit or 32-bit object pointers according to the mode
(HUGEPTRS
or NOHUGEPTRS
)
of the routine which included std::bad_exception
in its exception specification.
The AT&T compatible streams and complex library supports HUGEPTRS
. Note the cin
,
cout
, cerr
, and clog
streams refer to different objects (with different layouts)
in 64 and 32-bit modes. The Rogue Wave Standard C++ Library and Tools Library
do not support HUGEPTRS
.
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2004 by SAS Institute Inc., Cary, NC, USA. All rights reserved.