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.