|
Compaq C V6.4 for OpenVMS VAX Release Notes
7.20 Problems fixed in DEC C V5.2
This kit contains the following bug fixes beyond those contained in DEC
C V5.0-003:
- The 64K source line limitation on debugging C modules, previously
identified as a restriction, has now been removed.
- VMS source files with variable length record format could
sometimes provoke the message "%CLI-F-READERR, error reading filename,
-RMS-W-RTB, n-byte record too large for user's buffer." even for
records much smaller than 32K. This problem has been fixed. But note
that the advertised maximum source line length of 32767 bytes includes
an implicit newline terminator even for file formats that do not
explicitly represent the newline terminator charactor, and there are
some other boundary conditions with listings and error messages that
effectively reduce the actual line length fully supported to a few
characters less than 32767.
- /LIST/SHOW=NOSOURCE will no longer cause a compile time accvio
- CC/DECC/PREPROCESS_ONLY=filename SYS$INPUT no longer fails on
OpenVMS/VAX.
- SPR HPXQB8B17. Incorrect /OPT on VAX
Previously, DEC C/C++
erroneously put w in a register in the following case
unsigned int w = 17;
g(*(struct B *)&w);
|
- DEC C will now Skip parameter checks if we are evaluating an
operand to sizeof in common mode as in the example below:
j(int a)
{
p(sizeof(j()));
}
|
The severity of the messages concerning too many and too few
parameters is now a warning in VAXC mode (/STAND=VAXC) rather than an
error. This behavior is compatible with VAX C.
- Error messages have been relaxed for conflicting extern defs as
follows:
For /STAND=COMMON there is no change in behavior.
All extern declarations are promoted to file scope. When the compiler
encounters a conflicting declaration, it will issue a error as it has
always done. For /STAND=VAXC the severity of the error message has
been reduced to a warning.
VAX C issues a warning whenever it finds a conflicting extern
declaration. It does not matter if the declarations are in the same
name scopes or not. In addition to issuing a warning, VAX C replaces
the prior declaration with the new declaration from the point of the
new declaration onward. DEC C now matches this behavior in VAXC mode.
For /STAND=ANSI, /STAND=RELAXED
Errors will be generated, (as they always) if there is a conflict
between declarations that are in the same or inner name scopes. DEC
C will issue a warning if there is a conflict between names that are in
disjoint scopes. This will no longer be an E-level message. The
standard says that such a case is in error, but that a diagnostic does
not have to be issued. We felt that it was better to issue a diagnostic
than to silently accept the program. For example, in the program
shown below: /STANDARD=COMMON will result in no diagnostic messages.
/STANDARD=VAXC will result in a warning message about incompatibile
declarations for the second and third declaration of init_color
/STANDARD=RELAXED, /STANDARD=ANSI will result in an informational
diagnostic on the second declaration of init_color because it is
implicitly declared and will result in a warning on the third
declaration because it is incompatible with the declaration on line 3,
even though it is in a different scope.
main()
{
extern void init_color();
}
Raise_Maps()
{
init_color();
}
Title_Page()
{
extern void init_color();
}
|
- DEC C will no longer report a constant overflow if the left shift
operator causes the sign bit to change value. The ANSI C definition of
the left shift operation renders overflow inapplicable.
- A problem has been corrected which could cause an ACCVIO at
compile time when compiling with the qualifier /ANALYSIS_DATA.
- In all modes, functions declared at block scope will now have
their storage class set to extern. A warning is issued if the storage
class is register. A warning is also issued if the storage class is
auto (except in VAXC mode). If the storage is static, in common and
vaxc mode then no warning is issued for the declaration. But a warning
will issued later if the function is referrenced and not defined
anywhere in the module.
- SPR EVT101335
Whenever a call causes more than 255 items (longwords on VAX/quadwords
on Alpha) to be used in constructing the arg list a warning will be
issued. On Both VAX and Alpha an informational will be output warning
that the argument list length exceeds maximum specified by the calling
standard.
/* This program used to ACCVIO on VAX/VMS, now
it gets a compile-time diagnostic */
struct {
int i;
char longer_than_1020[1021];
} public_domain_sloppy_programmer;
void nothing();
main ()
{
nothing (public_domain_sloppy_programmer);
}
|
- SPR UVO102632 Formerly the compiler sometimes failed to issue a
diagnostic when an assignment was made to a constant array as in the
example below:
void fred (void)
{
typedef int A[2][3];
const A a = {{4, 5, 6}, {7, 8, 9}};
a[0][0] = 42;
}
|
- The compiler will now accept unnamed structures as members of a
struct in VAXC mode.
- The compiler will now issue a warning instead of an error when
pointers and ints are compared in common mode.
- The compiler will now issue a warning when preprocessing
directives are used in the argument list for a macro
- The compiler will now Allow more than just integers in switch and
case expressions in vaxc, and common modes. We now issue a new warning
when a float or pointer is used in a switch or case expression.
- A problem has been corrected involving the #dictionary directive
when it was nested within a structure declaration. The compiler now
correctly generates a member name for the extracted CDD record nested
within a struct, not a tag name.
- The macro definitions within a /define=(name[=value],...) list are
now processed left to right. Thus /DEFINE=(A=1,A=2) now leaves A
defined as 2 instead of 1.
- Problems with the /NESTED= qualifier have been fixed.
- The severity of the NONMULTALIGN message has been reduced to a
warning.
- Several problems in computing the value of an integer constant
constructed through token-pasting in the preprocessor have been fixed.
E.g. the following code formerly resulted in an incorrect message
"%CC-W-INVALTOKEN, Invalid token discarded".
#define concat(a,b) a ## b
return concat(0x0,1AL) ;
|
It now is handled correctly.
7.21 Problems fixed in DEC C V5.0
- DEC C in VAX C mode will now do macro subsitution in all three
cases below, just as VAX C did. Given the macros:
#define str1(arg) "arg"
#define str2(arg) "arg-ber"
#define str3(arg) "go to the arg"
|
- ICA-48945: mixing of old-style and new style function prototypes:
The compiler now allows mixing of new-style function prototypes and
old style function definitions where the prototype parameters are not
fully promoted integer types (according to default argument promotion
rules). With this modification, all integer type combinations are
allowed (including signed/unsigned mixing). A warning is issued where
we were issuing an E level error in the past (no message is issued if
in VAXC mode and the integer types in the old style parameter
definition match those in the prototype, as in the code fragment
provided in the SPR).
void f (char);
void f (p1)
char p1;
{}
$ cc/stand=vaxc foo.c
$ cc foo.c
char p1;
.....^
%CC-W-PROMOTMATCHW, In the definition of the
function "f", the promoted type of p1 is
incompatible with the type of the corresponding
parameter in a prior declaration.
at line number 3 in file DISK:[dir]FOO.C;1
|
In addition, the following will now correctly compile:
extern in (*f1())(int (*f2)());
int (*f1(f2))()
int (*f2)();
{ return 0;}
|
- HPXQ7084C CDD datatype text size 1, can now be converted be
converted to an array of char or to a char using the new #dictionary
keywords, text1_to_array, text1_to_char.
- The compiler will now give a diagnostic if C++ style comments are
used with /STANDARD= ANSI89.
- ICA49522 In vaxc mode, the compiler will now tolerate declarations
which contain redundant use of the type qualifer "volatile".
- DEC C used to issue messages for lexical "errors" appearing within
the bodies of macro definitions for macros that were never used. In
some cases these should not have been issued according to ANSI C (e.g.
warnings for octal constant containing digits 8 or 9), and generally
such potential problems do not require an ANSI diagnostics (e.g. the
effect of unterminated character constants is undefined). Common
practice is to defer such reports until a macro is used, which is what
DEC C now does.
- The result of compiling the output of the /PREPROCESS_ ONLY
qualifier was not always the same as the result of compiling the
original program. Consider the program below.
#define A(x) -x
main() {
int i = 1;
printf("%d\n", -A(i));
}
|
The output from /PREPROCESS_ONLY used to place the '-' of the body
of macro A next to the '-' before the macro invocation, producing:
Now the output has a space to separate the two '-' characters to
prevent this accidental token-pasting unless the compiler is in common
or vaxc modes, where this kind of token-pasting is done when compiling
the original source directly.
- curses.h
Changes have been made to improve the functionality of
the default curses package.
- float.h
On OpenVMS Alpha the D_FLOAT definitions of DBL_MAX and
LDBL_MAX were corrected.
- fp.h
The new header file <fp.h> implements some of the
features defined by the Numerical C Extensions Group of the ANSI X3J11
committee. Applications making extensive use of floating point
functions may find this useful. Some of the double precision DEC C
RTL functions return the value ±HUGE_VAL (defined in either
math.h or <fp.h>) if the result is out of range. The float
versions of those functions return the value HUGE_VALF (defined only in
<fp.h>) for the same conditions. The long double versions return
the value HUGE_VALL (also defined in <fp.h>).
- math.h
The D_FLOAT definition of HUGE_VAL was corrected on both
OpenVMS VAX and OpenVMS Alpha.
- ints.h
Definitions for (u)int16 and (u)int32 were added for use
by DEC C++ programs on OpenVMS VAX. This will allow DEC C programs
using (u)int16 or (u)int32 to be portable to DEC C++ on OpenVMS VAX.
- perror.h
Definitions for decc$ga_sys_errlist and
decc$gl_sys_nerr were added for use by DEC C and DEC C++ programs.
These are provided for compatibility with VAX C programs that made use
of sys_errlist and sys_nerr.
- setjmp.h
A prototype for decc$setjmp was added.
- stat.h
Macros defining constants for group and other protection
masks were added to match the ones for 'owner'.
- stdarg.h
A definition for va_count was added.
- stdio.h
Modifications were made to the definitions of clearerr,
feof, ferror such that proper usage of these macros does not give
warnings when compiling /WARNING=ENABLE=CHECK.
- unixlib.h
Prototypes were provided for the following routines
on OpenVMS VAX: decc$to_vms, decc$from_vms, decc$match_wild,
decc$fix_time, decc$translate_vms.
7.22 Problems Fixed in V4.0-01
- DEC C now recognizes comment terminators which span multiple lines
through the use of backslash, newline line continuation.
- The DEC C kit now installs properly on OpenVMS VAX V5.5-2.
- The DEC C kit now supplies the correct header files on systems on
which DEC C++ V1.2 was previously installed.
- The DEC C kit now ships CMA$DEF.H. Previous kits generated
CMA$DEF.H from SYS$LIBRARY:STARLETSD.TLB, and the generated version was
not correct.
- If DEC C encounters a bad multibyte character in a compilation
source, it attempts to skip past the character and continue compilation.
- In addition to
#pragma inline <function name>
, you can suggest inlining of a function with
__inline
. Below, both func1 and func2 are candidates for inlining:
__inline void func1(void} {}
void func2 (void) {}
#pragma inline func2
|
- Functions declared volatile or const via a typedef:
typedef int (F)();
const volatile F abs;
|
now produce a CONSTFUNC or VOLATILEFUNC diagnostic.
- Redundant type specifiers (e.g.
int int x;
) now produce warning diagnostics, not error diagnostics. Warning
diagnostics may be suppressed with /WARNING=DISABLE; error diagnostics
may not be suppressed.
- Similarly, improper use of register variables, such as:
register int x;
int *p = &x;
|
produces a warning diagnostic, not an error diagnostic.
- The redundant use of a type qualifier of a pointer (e.g.
int * const const p;
) produces a warning diagnostic.
- #include "'file.h'" no longer crashes the compiler.
- DEC C supports C++ style comments in all modes except
/STANDARD=ANSI89. DEC C cannot support C++ style comments in this mode
because they are not allowed by the C standard.
- DEC C for OpenVMS VAX supports the /NESTED_INCLUDE_DIRECTORY
command line qualifier. The default behavior is
/NESTED_INCLUDE_DIRECTORY=INCLUDE_FILE. This matches the behavior of
VAX C. See the DEC C User's Guide for OpenVMS Systems for more
information about this qualifier.
- #pragma __nostandard and #pragma __standard work correctly. In
some cases, the pair of pragmas were not suppressing some messages that
should have been suppressed, and leaving other messages suppressed that
should not have been suppressed.
- Most of the header files supplied with this kit or created during
installation compile with no diagnostics in all modes of the compiler
and with all diagnostics enabled. Some exceptions are:
- Headers files whose names contain $ give a DOLLARID diagnostic
when compiled with /WARNINGS=ENABLE=ALL. An identifier containing the
name of the file is used before the #pragma nostandard occurs.
- The generated CVT$ROUTINES.H, new in OpenVMS VAX V6.1, does not
compile in any mode of the compiler.
- The DEC C kit contains the header file, builtins.h.
- DEC C no longer requires definitions for unreferenced declared
objects. The following program no longer produces the linker diagnostic
%LINK-W-UNDFSYMS:
extern int x;
#include <stdio.h>
int main(void) {
printf("Hello world\n");
}
|
- DEC C no longer inlines functions that use va_start.
- In the /STANDARD=VAXC, /STANDARD=RELAXED_ANSI89, and
/STANDARD=COMMON modes of the compiler, a redeclaration of a function
with an empty argument list is now compatible with previous
declarations containing an ellipse. The following function declarations
are now compatible:
int x(int first, ...);
int x();
|
As required by the C Standard, DEC C does gives a FUNCREDECL diagnostic
for this in the /STANDARD=ANSI89 mode of the compiler. DEC C also gives
this diagnostic when you specify /WARNING=ENABLE=PORTABLE since such
redeclarations are not compatible in all implementations of C.
- Passing a pointer to an array of pointers to const chars to a
function expecting a pointer to a pointer to an array of pointers to
non-const chars now results in the following diagnostic:
static void f(char *argv[]) {}
static void g(const char *argv[])
{
f(argv);
%CC-W-PTRMISMATCH, (1) In this statement, the referenced
type of the pointer value "argv" is "pointer to const
char", which is not compatible with "pointer to char".
}
|
- DEC C supports the __int32 and __int16 datatypes.
7.23 Restrictions and known bugs
This is a list of some known compiler restrictions and bugs.
- The source file names and line numbers put into the object module
by the compiler for use by the debugger always reflect the actual
filespecs used by the compiler to access files during compilation, and
do not reflect any filenames or line numbers specified explicitly by
#line
directives within the source. This is a permanent restriction on the
VAX.
- The core "Transform" code of the MD5 message-digest algorithm, for
which there are public-domain versions and copyrighted versions from
RSA Data Security, cannot be compiled with optimization. This code
involves computation of a 16-byte hash value given an old 16-byte hash
value and 64 bytes of new data. The code represents the 16-byte hash
value as 4 unsigned ints, and proceeds in 64 steps, where each step
involves three computations and assignments to one of the 4 unsigned
ints constituting the hash value. The resulting straight-line sequence
of 192 assignments involves many complex expressions with values
flowing through the assignments. This triggers a pathological case in
the optimizer that exhibits n**2 behavior in the number of steps to be
optimized, which effectively appears to be an infinite loop at compile
time. The code can be correctly compiled only using
/optimize=nodisjoint
.
Some implementations of the algorithm do not mention the name
MD5, but the code can be recognized as follows. Given 4 integer
variables (h1, h2, h3, h4) holding the hash value, after macro
expansion the first of the 64 steps looks like:
h1 += (h4 ^ (h2 & (h3 ^ h4))) + input[0] + 0xd76aa478;
h1 = h1 << 7 | h1 >> 25;
h1 += h2;
|
- Under /NESTED_INCLUDE_DIRECTORY=PRIMARY_FILE, the sticky-default
processing for included files ignores filespec information from
top-level source files that are empty.
- There is a limit of 16 total text libraries that can be searched
in a compilation. This is a limit in the LBR$ utility routines, and is
a permanent restriction.
- There is a permanent restriction that header file searches
involving DECnet file specifications may not correctly interpret an
access string with password. This is because an expanded filespec is
actually used to open the files, and expanded filespecs are stored
without the password information for security reasons. Thus an attempt
to open the file using the expanded name will generally fail. The
DECnet access should be made without the need for a password (e.g.
through the default account or through a proxy).
- The _LOCC builtin function does not always work correctly if an
optional fourth argument is specified and if compiled /NOOPTIMIZE. In
the following example, DEC C is not updating p_c after the second call
to _LOCC. Thus, the program prints out
node-+
instead of
node-:
.
#include <stdio.h>
#pragma builtins
int main(void) {
char name[]= "node:: ", *p_c;
char **pp_c = &p_c;
_LOCC ( ':', sizeof(name), &name, &p_c );
*p_c++ = '-';
_LOCC ( '+', sizeof(name), &name, pp_c );
*p_c++ = '+';
printf(name);
}
|
- DEC C does not warn about C++ style comments with
/WARNINGS=ENABLE=PORTABLE.
- If your code includes assert.h multiple times and uses the text
library form of inclusion,
#include assert
, the first include will work correctly. But, the second include causes
the compiler to issue an error message about an invalid include file
name. This is because assert have been defined as a macro within
assert.h, so the compiler is looking a the macro expanded file name,
which does not exist. The assert macro may be used elsewhere without
any problems.
Digital recommends that you avoid the text library
form of inclusion for assert.h. Use
#include <assert.h>
instead.
- In some rare cases DEC C will enter an infinite loop trying to
optimize control flow involving constant expressions. The simplest
example occurs below.
void f() {
if (0) {}
while (1) if (0);
}
|
Small changes to the source that do not affect the sense of the program
allow the compiler to successfully compile the code. In the above
example, replacing the
{}
with
;
allows the compiler to compile the code successfully. Removing the
if (0)
pieces of the code altogether also fixes the problem.
- DEC C cannot handle extremely long types when compiling with
/DEBUG. The types have to be something on the order of:
long ***************************************************
***************************************************
***************************************************
***************************************************
***************************************************
*********************************************a;
|
to exhibit the problem.
- In some rare cases, DEC C does not inline functions correctly. The
only known instance of incorrect inlining is for the following program:
#include <stdio.h>
static int called(int);
/* Adding #pragma noinline called makes this work */
int main (void) {
volatile int zz = 1;
printf("Hello World!\n");
printf("Answer is: %d should be (12)\n",caller(zz));
}
int caller( int sw) {
switch(sw) {
case 0: return called(3); break;
case 1: return called(3); break;
}
}
int called(int k) {
struct {int table[4000];} *p=0;
return (int)&(p->table[k]);
}
|
Instead of an answer of 12, the answer is garbage.
- DEC C produces the wrong debugging information for automatic
doubles, making it impossible to examine their values with the debugger.
main(){
double db = 34.439; /* can't be examined */
static double sb = 45.54; /* can be examined */
}
|
- The /SHOW=TRANSLATION qualifier does not work. The information it
places into the listing file is not correct.
- The default for the /PREFIX_LIBRARY_ENTRIES is ALL, even in the
/STANDARD=ANSI89 and /STANDARD=RELAXED_ANSI89 modes of the compiler. If
you are defining functions whose names conflict with names in the DEC C
RTL, e.g. open, you will get multiply defined symbol warnings from the
linker. If so, use /PREFIX_LIBRARY_ENTRIES=ANSI_C89_ENTRIES.
- Certain programs with a loop containing a goto that goes to a
label outside the loop, which in turn contains a goto back into the
loop, will run incorrectly when compiled with optimization turned on.
They run correctly with optimization turned off. An example of such a
program is:
extern sub1();
extern sub2();
extern sub3();
main()
{
int i, j, k;
for (i=0; i<1; i++)
for (j=0; j<1; j++)
{
goto label2;
label1:
sub4(); sub5(); sub6();
}
return;
label2:
for (k=0; k<1; k++)
{
sub1(); sub2(); sub3();
}
goto label1;
}
|
- The diagnostic for array declarations with more than INT_MAX
elements is misleading. It should state that there are too many
elements in the array.
- Listing file line numbers wrap to 0 after reaching 64k.
- If a file includes itself, the compilation eventually fails with
the error that it could not open the include file because the file
could not be found or had the wrong protection. It should fail with an
error that it reached the maximum number of include files that it could
handle.
- Extremely large, sparse switch statements cause the compiler to
generate code that when linked is far larger than necessary. In the
case reported, a switch statement whose range (the difference between
the highest case label and the lowest case label) was about 35000 and
only had 2000 case labels inside the switch was over 20 megabytes large
when linked. The problem only seems to appear for switch statements
whose range is in the tens of thousands and where the number of case
labels is slightly more than 5% of the range of the case.
One
workaround for this problem is to add an extra case label that
increases the range of the switch so that the number of case labels
falls below 5% of the range (for example, add case 100000: just before
the case that handles bad switch indexes). This will cause the compiler
effectively to turn the switch statement into a long sequence of
if-then else-if statements. The best workaround is to rewrite the
switch into a series of smaller, more densely packed switch statements
or to choose an alternate implementation altogether (for example, a
table search that returns an index into an array of functions).
- There is a memory leak in the compiler noticed when compiling a
comma-separated list of source files. If you get an error about memory
limits exceeded when using comma lists, recompile each file separately.
- DEC C does not always diagnose function argument lists longer than
255 arguments. Compiling the code causes a COMPILERBUG diagnostic
unless DEC C inlines the function.
- On OpenVMS VAX systems prior to V6.1, there was a problem with the
relaxed_refdef external model. Under the external model relaxed_refdef,
an uninitialized declaration of an external variable that left off the
keyword
extern
was not associated with either a definition of the global variable
under strict_refdef, or an initialized definition of the global
variable under relaxed_refdef. For example, assume module A.C was
compiled /EXTERN_MODEL=RELAXED_REFDEF and contained the declaration:
/* relaxed_refdef --> tentative definition */
int global_var;
|
and module B.C was compiled /EXTERN_MODEL=STRICT_REFDEF and contained
the declaration:
/* strict_refdef --> definition */
int global_var;
|
or the module B.C was compiled /EXTERN_MODEL=RELAXED_REFDEF and
contained the declaration:
|