5 Known Problems and Workarounds
- 1 -
1. Introduction
This document contains information about the C compiler
driver, preprocessors, and front ends (both traditional and
ANSI C). Utilities, header files, and libraries common to
several languages are covered in Chapters 3, 4, and 5 of the
5.2 Base Development Release Notes (accessed as the dev
release notes).
Note: Packaged with this software is a separate sheet that
contains the Software License Agreement. This
software is provided to you solely under the terms
and conditions of the Software License Agreement.
Please take a few moments to review the Agreement.
This document contains the following chapters:
1. Introduction
2. Installation Information
3. Changes and Additions
4. Bug Fixes
5. Known Problems and Workarounds
In addition, Appendix A discusses dynamically shared objects
(DSOs).
1.1 Release_Identification_Information
Following is the release identification information for ANSI
C:
Software Option Product ANSI C
Version 3.18
Product Code SC4-IDO-5.2
Software Requirements IRIX 5.2
IRIS Development
Option 5.2
- 2 -
1.2 Online_Release_Notes
After you install the online documentation for a product
(the relnotes subsystem), you can view the release notes on
your screen.
If you have a graphics system, select ``Release Notes'' from
the Tools submenu of the Toolchest. This displays the
grelnotes(1) graphical browser for the online release notes.
Refer to the grelnotes(1) man page for information on
options to this command.
If you do not have a graphics system, you can use the
relnotes command. Refer to the relnotes(1) man page for
accessing the online release notes.
1.3 Product_Support
Silicon Graphics, Inc., provides a comprehensive product
support maintenance program for its products.
If you are in North America and would like support for your
Silicon Graphics-supported products, contact the Technical
Assistance Center at 1-800-800-4SGI.
If you are outside North America, contact the Silicon
Graphics subsidiary or authorized distributor in your
country.
- 1 -
2. Installation_Information
This chapter lists supplemental information to the IRIS
Software Installation Guide. The information listed here is
product-specific; use it with the installation guide to
install this product.
2.1 ANSI_C_Subsystems
ANSI C includes these subsystems:
c_dev.books.CLanguageRef Insight-readable version of the
compiler and C programmer's reference
guide
c_dev.man.c Manual page for the cc driver
c_dev.man.util Manual pages for C source utilities
(cflow, cb, and so on)
c_dev.man.relnotes Online version of these release notes
c_dev.sw.c The C front ends and preprocessors
c_dev.src.acpp The C source for the ANSI preprocessor
acpp
c_dev.sw.copt The C scalar optimizer
c_dev.hdr.lib copt-specific header files
(kapio.internal.h, kapio.sgi.h)
c_dev.sw.lib opt-specific I/O archive for shared
compiles (libkapio.a)
c_dev.sw.speclib copt-specific I/O archive for non-shared
compiles (libkapio.a)
c_dev.sw.util The C source utilities (cflow, cb, and
so on)
c_dev.man.copt The C scalar optimizer manual pages
2.2 ANSI_C_Subsystem_Disk_Space_Requirements
This section lists the subsystems (and their sizes) of the
ANSI C option.
If you are installing this option for the first time, the
subsystems marked ``default'' are those that are installed
- 2 -
if you use the ``go'' menu item. To install a different set
of subsystems, use the ``install,'' ``remove,'' ``keep,''
and ``step'' commands in inst to customize the list of
subsystems to be installed, then select the ``go'' menu
item.
Note: The listed subsystem sizes are approximate. Refer to
the IRIS Software Installation Guide for information
on finding exact sizes.
Subsystem Name Subsystem Size
(512-byte blocks)
c_dev.books.CLanguageRef (default) 2180
c_dev.man.c (default) 82
c_dev.man.util (default) 81
c_dev.man.relnotes (default) 172
c_dev.sw.c (default) 1918
c_dev.sw.copt (default) 6097
c_dev.hdr.lib (default) 4
c_dev.sw.lib (default) 82
c_dev.sw.speclib 75
c_dev.sw.util (default) 2358
c_dev.man.copt (default) 49
c_dev.src.acpp (default) 549
2.3 Installation_Method
All of the subsystems for ANSI C can be installed using
IRIX. You do not need to use the miniroot. Refer to the
IRIS Software Installation Guide for complete installation
instructions.
2.4 Prerequisites
ANSI C 3.18 requires the installation of the IRIS
Development Option (compilers portion) release 5.2. For the
compiler subsystems, refer to Chapter 2 of the 3.18 Base
Compiler Release Notes.
2.5 Compatibility
ANSI C release 3.18 is compatible generally with previous
versions. The frontend and preprocessor have been replaced
by cfe. There are a few incompatibilities, which are
described in Chapter 3 (Changes and Additions).
- 3 -
- 1 -
3. Changes_and_Additions
This chapter details significant changes and additions made
to the ANSI C product since the 2.0.1 version of ANSI C,
released with IRIX 4D1-4.0.1.
3.1 General_Compiler_Changes
The following compiler changes are of general interest:
o String literals, except as initializers of non-const
array variables, may always be allocated to a "read-
only" data section according to ANSI/ISO. Furthermore,
a const qualified aggregate (struct/array) object,
without any pointer subcomponent and initialized with a
value that does not depend on any (relocatable) object
address, may also always be allocated to a read-only
data section in ANSI/ISO C. We now group such constant
values together in a "read-only" section in the
compiled object, since they will not be modified in an
ANSI/ISO conformant application. This is particularly
beneficial when building .so's (see Appendix A), since
the "read-only" section can be shared between
executables. However, many sources are not strictly
ANSI/ISO conformant, and for this reason the "read-
only" section is by default put into a writable data-
segment of the execution process. With the "read-only"
section being writable, we may still get the benefits
of sharing for .so's provided the section is not
actually written to. To force the "read-only" section
into a truly read-only data-segment, we provide the new
option -rodata_shared.
o The default compilation mode of the compiler since 3.16
is shared. -O3 optimization might not work in this
release, because -O3 must be used with the -non_shared
option and all of the nonshared libraries might not be
on the system to complete linking. If you use -O3 and
the necessary libraries are not there, you get a
compile-time error from uld (the ucode linker)
indicating the fact. The non-shared version of the
libraries is not installed by default, so you have to
select these libraries specifically for installation if
you wish to use either -O3 or -non-shared by itself.
o The -volatile option is no longer supported. Users who
relied on this option should instead use the "volatile"
type qualifier where required.
o The type long long is fully supported. Because long
long is not strictly ANSI C, you will get a warning for
- 2 -
any explicit occurrences of this type in -ansi and
-ansiposix modes. If you refer to types __int64_t or
__uint64_t, or use any library routines that refer to
these types, define the macro _LONGLONG on the command
line to take advantage of the support for long long in
-ansi and -ansiposix modes; otherwise, __int64_t and
__uint64_t are defined by means of structs. The
warning 'long long' is not standard ANSI. (3.1.1) will
be issued regardless of the macro _LONGLONG being
defined or not.
o A -wlint option was added in 3.16 to obtain lint-like
warnings during compilation. This lint-like feature
understands ANSI C and can be activated together with
any of the other compiler options. The lint command
does not support "long long" types, nor does it operate
in the exact same compile modes (-cckr, -xansi, -ansi)
as does our C compiler; see the lint(1) man pages for
further information. We strongly recommend using the
-wlint option instead of lint, whenever possible, for
extensive source code diagnostics. The -wlint option
is described in the cc(1) man page. Below are the
warnings that are activated, in addition to the regular
compiler warnings, with the -wlint option:
- The -wlint,-p (portability) option warns about
identifiers that are ambiguous in their first
eight (8) characters. This option also warns
about (in)equality expressions (that is, ``<'',
``<='', ``>'', ``>='', ``!='', or ``=='') applied
to a char and a negative constant as arguments,
assuming such comparisons are based on the non-
portable assumption that chars are signed.
- Warning about incomplete structs/unions/enums and
unused static variables. This warning can be
suppressed with the -wlint,-u option.
- Warning about main not having an integral return
type.
- Warning about functions with a return type but
without a return statement along some control path
(that is, a random value can be returned). This
warning can be suppressed with the -wlint,-h
option.
- Warning about function declarations without
prototypes and for calls to such functions.
- 3 -
- For a call to a non-prototyped function, a warning
about incompatibilities between the types of
promoted arguments and the types of the
corresponding promoted parameters.
- Warning about control falling through (case)
labeled statements. This warning can be
suppressed with the -wlint,-h option.
- Warning about statements that are unreachable.
This warning can be suppressed with the -wlint,-h
option.
- Warning about a register storage-class specifier
in association with a type that is not
registerable (that is, arrays, struct, unions, and
functions).
- For an array with a declared size, warn about
constant index values outside the range: [0..size
-1].
- Warning about explicit casts from a pointer type
to a smaller integral type (e.g. (short)(char *)5)
and from an integral type to a larger pointer type
(for example, (char *)(short)5). This warning can
be suppressed with the -wlint,-z option.
- Given an unsigned operand ``u'' and a negative
constant operand ``n'', a warning is issued about
comparison expression: u!=n, u==n, u>n, u>=n,
u=0, and u<0. Also warns about the
symmetric cases (that is, n!=u, n>u, etc.). This
warning can be suppressed with the -wlint,-h
option.
- Warning about implicit conversions that can lead
to a loss of accuracy, such as assigning an int
(32 bits) to a short (16 bits). This warning can
be suppressed with the -wlint,-a option.
- Warning about implicit conversions that do not
lead to a loss of accuracy. This warning can be
suppressed with the -wlint,-i option.
- Warning about hexadecimal and octal constants
where the value of every bit is not explicitly
given (for example, warn about 0xfff and 077, but
not 0x00000fff and 000000000077). This warning
can be suppressed with the -wlint,-h option.
- 4 -
- Warning about unused function parameters. This
warning can be suppressed with the -wlint,-v
option.
- Warning about unused automatic variables.
- Warning about unused labels (that is, labels that
are never jumped to).
- Warning about variables that are used (accessed as
rvalues) before they are set (assigned to);
warning about variables that are set but never
used.
Finer control of warning suppression can be achieved
with the -woff option. By default -wlint warnings are
formatted in a lint-like manner, while the -wlint,-f
option formats warnings like the compiler normally
does.
o The messages issued by the front end have been slightly
changed. The warning numbers have been changed also.
Refer to the new warning numbers when using the -woff
option (as described in the cc(1) man page).
o It may be worthwhile noting the behavior when accessing
a field of a volatile struct/union. The ANSI standard
is rather vague on this point. For an arbitrary
expression exp that evaluates to a volatile
struct/union, should you load the whole struct/union
when only a field is selected? For:
exp.field
this version of the compiler loads only the selected
field as a volatile data object, not the whole
struct/union denoted by exp. Also, note that a
volatile struct/union object is passed by reference
when appearing as an argument to a function, and only
the address - not the value - of the object is accessed
on the caller side. For example, for:
f(exp);
only the address of exp is accessed at the point of
call.
o New man pages have been added for the -mips2 and -mips3
compiler options (accessible with man mips2 and man
mips3, respectively. These man pages explain the
benefits of using the MIPSII and MIPSIII extensions to
the R4000 instruction set.
- 5 -
o The option -MDupdate filename is understood by the
compilers and linker. For example, -MDupdate
Makedepend produces a Makedepend file that accurately
mentions all header and library dependencies as a
byproduct of compilation and linking. Makes that depend
on the Makedepend file are now 100% complete and
accurate. This makes the -M option unnecessary.
o Support for weak symbols has been added to the compiler
front ends. A weak symbol may be associated with an
external symbol by the appearance of a new #pragma
directive in the C source code. At link time, a weak
definition is ignored unless it is the only definition
that satisfies a reference (for example, it does not
conflict with a non-weak definition of the same name in
a different file or library). A weak symbol is simply
an alias for an existing non-weak symbol, and must
appear in the same file as the non-weak definition.
Use of weak symbols makes it easier to change the
definition of a symbol while avoiding conflicts of
definition.
If you want to associate a weak symbol foo with a
defined symbol _foo, then declare foo as an extern
followed by the directive:
#pragma weak foo = _foo
The following restrictions are important when declaring
weak symbols:
- The The above weak definition of foo must be in
the same file as the definition of _foo.
- If _foo is a data object, it must be initialized.
- A non-extern declaration of foo, in the same or
another linked in compilation unit, will override
the weak definition.
- Note the problem noted in section 5.2 for weak
definitions combined with constant propagation
optimization.
o A new scalar optimizer pass (copt) has been added to
the C compilers. It is invoked with the -sopt switch.
Options to copt control the types of optimizations done
and are described in the copt(1) man page.
- 6 -
3.2 Changes and Additions to the C Frontend and
Preprocessor
o Special characters (such as ``,'' ``/'' ``.'' ``}''
...) trailing a macro name are no longer ignored by
the preprocessor in -cckr mode. This was a cpp
problem, which did not occur in acpp. For example, M1
in the following piece of code:
#define M1, 24
used to be expanded by cpp to: " 24" , whereas now
it expands to: ", 24" in all modes (-cckr, -ansi,
-xansi).
o cfe warns about more than one type specifier in a
declaration, in all modes (-cckr, -ansi, -xansi). For
example, the following code fragment was erroneously
supported by ccom, but gets a syntax error from cfe.
typedef struct snif_sap_list {
int t;
} snif_sap_list_t;
int snif_sap_list_t *snif_add_sap();
main(){}
o cfe issues a syntax error for array initializations of
the following form:
char a[]={1,2,"my string"};
This was supported by ccom and accom, though it
violates the ANSI standard.
o cfe warns about a type qualifier for void type, in all
modes. ccom was silent about it, while accom also
complained. For example:
main() {
unsigned void * ptr;
}
now gets the error: invalid combination of type
specifiers in -cckr mode.
o cfe now supports a pragma of the form:
#pragma intrinsic(op)
to inline selected operations from and
. The pragma has effect only when op is
- 7 -
sqrt, sqrtf, fabs, fabsf, or strcpy. For other
arguments the pragma has no effect. Functions sqrt and
sqrtf are inlined only for -mips3 and -mips2 modes,
because the MIPS I instruction set does not contain a
sqrt instruction. In this version of the compiler:
#pragma intrinsic(strcpy)
has the same effect as did:
#pragma sgi_str_inline
in an earlier version of the C compiler. Note that
making intrinsic any of the functions violates
the ANSI standard, because errno will not be correctly
set.
In -cckr and -xansi modes, the C driver passes
-D__INLINE_INTRINSICS to the driver by default, which
makes all of sqrt, sqrtf, fabs, fabsf, and strcpy
intrinsic. This is not the default behavior in -ansi
and -ansiposix modes, due to the errno restriction
noted above. Of course, this default can be overridden
by passing -D__INLINE_INTRINSICS to the driver in -ansi
or -ansiposix mode, or by passing -U__INLINE_INTRINSICS
to the driver in -cckr or -xansi mode.
- 1 -
4. Bugs_Fixed
This chapter details bugs fixed in the C product since the
2.0.1 version of ANSI C released with IRIX 4D1-4.0.1. The
following fix descriptions apply to both the Traditional and
ANSI C front-ends, unless otherwise noted. Except where
noted, a bug fixed in a particular release is fixed in all
subsequent releases. Some of the bug descriptions are
followed by a Silicon Graphics, Inc. incident number in
parenthesis.
4.1 Bugs_Fixed_in_3.18
o The indirection entries in the debugging symbol table,
mentioned in section 4.2, are now tagged as "Indirect"
entries instead of using arcane "Typedef" entries for
this purpose.
o Warnings are now emitted for infinite recursion during
macro expansion in -cckr mode. By default, the number
of recursive macro expansions may not exceed 300, but
this can be altered with the -Wp,-max_rec_depth=depth
cc command line option. Earlier, the compiler went
into an infinite loop when expanding (mutually)
recursive macros (136971).
4.2 Bugs_Fixed_in_3.17
o Indirection entries (in the form of nameless typedef
entries) were not always generated in the symbol table
for incomplete struct/union definitions when cc was
invoked with the -g flag. When several incomplete
types were completed in different order in different
objects, the symbol table for a given file could differ
between objects and the inter-file references to the
(now completed) types became wrong when the linker
merged the objects. Because of this, cvd would
evaluate expressions incorrectly. This problem is
fixed by always using the indirection entries for types
that are first encountered as incomplete types.
(148436, 150923, 163006, and 164737)
o Using the -wlint option to cc with the -q option (issue
lint diagnostics and exit without compiling) would
sometimes create the file lint_htmpfile and leave it
behind after the command finshed executing. This file
is no longer created. (150549)
o A conversion of an ``unsigned'' left-shift expression
to type ``double'' would sometimes yield incorrect
results. This occurred because constant integral
- 2 -
values are internally in the compiler represented in 64
bits and a constant folding of the ``<<'' operator took
place without sign sensitivity. This has been fixed by
making the constant folding sign-sensitive. (151986)
o By default, cfe now produces a warning in the event of
a lift shift with a negative right operand, or a right
operand that is greater than or equal to the width in
bits of the promoted left operand. This complies with
ANSI standard behavior. (153152)
4.3 Bugs_Fixed_in_3.16
o ANSI C is no longer confused by a function and
parameter that have the same name, or a structure
member and a parameter with the same name.
o ANSI C now knows to set the ``volatile'' attribute to
all members of a volatile structure.
o There is no longer a restriction on alloca.
o The compiler front ends used to generate incorrect code
for a statement like:
*n2 = getpair(n1).a;
o cc generated bogus line numbers for a FOR-loop in the
presence of a break. This has been fixed.
o There is no further need to extend the internal table
sizes.
o cc did not report invalid assignments to non-const in
an initializer. Now it does.
o An untyped declaration inside a struct or union can now
be referenced.
o Compiling with the option -S, which resulted in an
incorrectly terminated comment in the assembly file,
has been fixed.
o A bogus error message produced by array initialization
has been eliminated.
o An element of an array of char did not default to a
pointer to unsigned char. This has been fixed.
o The front end used to core dump on:
- 3 -
char a [ ] =* "";
It no longer does.
o The front end used to give an internal error on:
#\
and on:
char foo[] = {
bar("abc"),
bar("123"),
bar("def"),
bar("walter")
};
These have been fixed.
o An incorrect warning message for bit-field assignment
no longer appears.
o Referencing a substructure member from one struct as an
offset from a totally different type of struct used to
give a warning only with the -fullwarn option. Now it
gives an error in the ANSI modes.
o The internal error in -cckr mode for the test case:
typedef void PROC (long, char*);
PROC do_first;
has been fixed.
o #ifel is now handled correctly.
o Preprocessing with -cckr produced incorrect line
numbers. This has been fixed.
4.4 Bugs_Fixed_in_3.10,_3.10.1_and_3.15
o The ar command did not handle relative symbolic links
properly. This was fixed in 3.10.1. (118276)
o In as1, the value of doubles was passed incorrectly.
The order of the two words was reversed when passed to
a routine. This was fixed in 3.10.1. (119193)
o When using cc with -O2 optimization, uopt loop
unrolling produced incorrect code. This was fixed in
3.10.1. (121121)
- 4 -
o ELF versions of lorder (and other utilities) did not
work properly on a 4.0.5 library. This was fixed by
padding namefields. (123156)
o ar did not allow extracting files into a directory
other than the current one. This was fixed in 3.10.1.
(125676)
o usr/lib/fixade.o was stripped in the 3.10 distribution.
This caused problems for some users, so all subsequent
versions are shipped unstripped. (126483)
o In the 3.10 version of the compilers, the message as1:
Warning: ... Mips III opcode used without -mips3
sometimes appeared due to a mips3 uld instruction
generated erroneously by ugen. (126485)
o ugen sometimes suffered a fatal error when compiling
very large programs. This was fixed in 3.10. (127524)
o A program compiled with -O2 optimization sometimes
optimized a function incorrectly, producing wrong
results. This was fixed in 3.10.1. (127577)
o Copy propagation at -O2 optimization level in the
assembler caused the floating point load instructions
to be wrong. This was fixed in 3.15. (128694)
o Using pixstats with the -disassembl option generated
extra cfc instructions. (131302)
o A compound statement with assignment addition and
relational operation evoked a fatal error. This was
fixed in 3.10.1. (131394).
o nm dumped core on the command:
cd /usr/lib; nm *.a > nm.out.
This was fixed in 3.15. (131788).
o Programs compiled and linked using the -mp option,
running under single thread, generated a
/tmp/mpLockfile.*. This was fixed in 3.15. (133059)
o When compiling with the -Olimit option, uopt failed
when out of swap space and gave the message Fatal error
in /usr/lib/uopt Signal 9. The fix for this problem
consisted of providing a more informative error
message. (133311)
- 5 -
o Correct arguments were passed if code was compiled with
-O3, but not with other levels. (133638)
o The mp_schedtype=dynamic assignment in a parallel loop
produced a run-time bus error and dumped core. This
was fixed in 3.10.1. (136326).
o Code generated by the optimizer used $31 as the target
register in a jalr, which is incorrect. It produced the
error message as1: JAL should not use $31 alone or any
register twice.
(137584 ).
o A line of code was sometimes optimized out when using
-O2. This was a problem in uopt, fixed in 3.10.1.
(137627).
4.5 Bugs_Fixed_in_Previous_Versions
o ANSI C no longer produces messages such as: illegal
character: 134 (octal) following syntax errors unless
the message is actually warranted. The message never
came out unless there were fatal syntax errors.
o ANSI C: Certain statements involving ?: and casts to
types with function prototypes generated error messages
when they should not. This has been fixed.
o ANSI C: In rare circumstances, function prototype
comparisons were not performed completely and allowed
illegal function calls. This no longer occurs.
- 1 -
5. Known_Problems_and_Workarounds
Unless otherwise indicated, the following bugs in the C
compiler release 3.18 apply to both Traditional C and ANSI
C.
5.1 Preprocessor
o The following is permitted by the cfe preprocessor:
#undef __STDC__
However, it should be illegal.
o The source location for ``f()'' in:
# /* some rather
lengthy
and multi-line
comment */
void f(void) {...}
will be wrongly perceived by cfe to begin at the line
where the comment starts, since the "#" is assumed to
be a line-directive while the whole comment is viewed
as a single space within the line-directive. This will
cause dbx to list the wrong source lines for statements
in the body of ``f()''.
5.2 Known_Compiler_Problems
o An indexing expression with a complicated index
expression may sometime generate illegal ucode, which
causes ugen to core dump. A workaround is to move the
index expression out and assign it to a temorary
variable, or just change the expression. The following
illustrates the only known case of this happening:
char board[19];
int capture[2];
setboard (int x)
{
capture[!(board[x])]++; /* Ugen coredumps on this! */
capture[(board[x])?0:1]++; /* This works just fine! */
}
o Bitfield extraction always yields a value with a signed
integral type (ID #200899). If structure ``s'' has a
bitfield ``unsigned int b:10;'', then ``s.b'' will be
incorrectly typed as ``int". This may cause unexpected
- 2 -
results in contexts where the enclosing expression
assumes the type of ``s.b''. As an example, consider:
#include
struct S
{
unsigned int a : 12;
unsigned int b : 10;
unsigned int c : 10;
} s;
void f(void)
{
int i = (int)0x7fffffff;
s.b = 3;
if (i + s.b < 0)
printf("This is unexpected");
else
printf("As expected");
}
This will print the ``unexpected'' message. The
workaround is to explicitly cast the bitfield
expression to ``(unsigned int)s.b''.
o Very long source lines (more than 1K characters) may
cause a segmentation fault in cfe if a diagnostic
message is emitted for this source line.
o A standalone lint is available, but it does not support
the same options and compilation modes supported by the
C compiler (it supports the the AT&T SVR4 compilation
modes, and treats ``long long'' types as ``long'').
Unless lint is used to handle lint-directives, to
provide lint2 diagnostics, or to produce the lint
output files, we instead strongly recommend use of the
-wlint option with the cc command. This option works
with all the other compiler options and flags,
including compilation in ANSI mode. Note that -wlint
does not produce the traditional output files from the
lint passes, nor does it handle lint directives, while
it does provide lint-like diagnostics.
o The -wlint option causes an incorrect ``implicit type
conversion'' warning when an enumerator is assigned to
an enumeration variable, and may also cause incorrect
``used before set'' warnings for variables in the
controlling expressions of loops:
- 3 -
void
foo(int *head)
{
enum E {e1, e2, e3} c;
int *p, *nextp;
int i;
/* incorrect warning: "implicit conversion from int to enum" */
c = e1;
/* incorrect warning: "i may be used before set" */
do {i = *(p++);} while (!i);
/* incorrect warning: "nextp may be used before set" */
for (p = head; p; p = nextp) nextp = p;
}
o There is a problem with constant propagation in the
context of weakextern definitions. For the source:
#include
extern int a;
#pragma weak a=b
int b = 3;
main()
{
a = 5;
printf("%d, %d", a, b);
}
the output when compiled without any optimization (-O0)
``5, 5'', as expected, while with optimization the
output is ``5, 3''. The latter is a result of
constant propagation, which reduces the body of
``main()'' to:
printf("%d, %d", 5, b);
thus effectively eliminating the assignment to ``a''
and its alias ``b''.
5.3 Known_Problems_with_Workarounds
o In 3.17 and earlier versions of the compiler, no
diagnostics were emitted (by default) in -cckr mode for
a function redeclaration with incompatible parameter
types. This could be highly error-prone, since an
argument could be passed to the same function in
differing ways, dependent on which declaration were in
scope at the point of call. Consider the following
- 4 -
code:
#include
int f(float f1, float f2);
f(f1, f2)
float f1, f2;
{
printf("f1=%g, f2=%g0, f1, f2);
}
main()
{
f(17.17, 17.17);
}
The unprototyped function definition expects float
arguments to be promoted to doubles (64 bits entities),
while the call in fact heeds the prototype and passes
the arguments as floats (32 bits entities). The values
printed will be unpredictable. To avoid this kind of
unexpected behaviour we highly recommend that users
compile their code with -prototypes in -cckr mode. For
redeclarations, where references to parameters in the
function body may access a different bit pattern than
that passed on the caller site (as in the above
example), we now issue an error in -cckr mode. Other
forms of incompatible redeclarations still pass without
any diagnostics. The old (ccom) compiler sometimes
succesfully combined such incompatible redeclarations,
but not always. We therefore found it sounder to
disallow the most blatant forms of mismatches in this
version of the compiler.
o Note that lint incorrectly diagnoses a syntax error for
the latter of the following two declarations for
``XSynchronize'':
typedef int Display;
extern int (*XSynchronize(int*))();
extern int (*XSynchronize(Display*))();
The first form of declaration (without the typedef) can
be used as a workaround for this particular problem.
o The compiler will incorrectly diagnose the last of the
initializers in the following code fragment as an
incorrect initializing expression:
- 5 -
typedef unsigned int size_t;
typedef struct uacdef
{
unsigned int *uacind;
unsigned int *uacaln;
unsigned int *uacrcp;
unsigned int *uaccal;
} uacdef;
size_t uacsiz[] = {
(size_t)&(((uacdef*)0))->uacrcp,
(1&0x40 ? sizeof(uacdef) : (unsigned int)&(((uacdef*)0))->uacrcp),
(1&0x40 ? sizeof(uacdef) : (size_t)&(((uacdef*)0))->uacrcp)
};
The first two forms of initializers may be used as a
workaround for this problem.
o Benchmarks using computational kernels that operate on
arrays with dimensions of a modulus of the cache size
can cause cache line thrashing. This condition will
usually manifest in a program taking much longer to
compile than expected, and can be analyzed further by
monitoring system performance statistics such as I/O
use during compilation. The remedy is to increase the
size of the array by a multiple of the cache line size.
Because cache line size is fixed for each specific
architecture, check your hardware documentation to see
what applies for your system. (126115)
- 1 -
1. Dynamic_Shared_Objects
A Dynamic Shared Object, or DSO, is an ELF format object
file, very similar in structure to an executable program but
with no "main". It has a shared component, consisting of
shared text and read-only data; a private component,
consisting of data and the GOT (Global Offset Table);
several sections that hold information necessary to load and
link the object; and a liblist, the list of other shared
objects referenced by this object. Most of the libraries
supplied by SGI are available as dynamic shared objects.
A DSO is relocatable at runtime; it can be loaded at any
virtual address. A consequence of this is that all
references to external symbols must be resolved at runtime.
References from the private region (.e.g. from private data)
are resolved once at load-time; references from the shared
region (e.g. from shared text) must go through an
indirection table (GOT) and hence have a small performance
penalty associated with them.
Code compiled for use in a shared object is referred to as
Position Independent Code (PIC), whereas non-PIC is usually
referred to as non-shared. Non-shared code and PIC cannot
be mixed in the same object.
At Runtime, exec loads the main program and then loads rld,
the runtime linking loader, which finishes the exec
operation. Starting with main's liblist, rld loads each
shared object on the list, reads that object's liblist, and
repeats the operation until all shared objects have been
loaded. Next, rld allocates common and fixes up symbolic
references in each loaded object. (This is necessary
because we don't know until runtime where the object will be
loaded.) Next, each object's init code is executed.
Finally, control is transferred to "__start".
For a more complete discussion of DSOs, including answers to
questions frequently asked about them, see the dso(5) man
page.