Command-line options for specifying strict conformance to the C++ standard are listed in Table 1-37. Instructions for enforcing strict conformance from your IDE are given in Table 1-38.
Tip
Some of the compiler options I introduced in Table 1-6 can be considered conformance options. Examples include options to enable basic language features such as wide-character support, exceptions, and runtime type information. I’ve omitted these in Table 1-37.
Table 1-37. Enforcing strict conformance from the command line
Toolset |
Command-line compiler options |
---|---|
GCC |
-ansi -pedantic-errors |
Visual C++ |
-Za |
Intel (Windows) |
-Za -Qms0 |
Intel (Linux) |
-strict-ansi [19] |
Metrowerks |
-ansi strict -iso_templates on -msext off |
Comeau (Windows) |
—A |
Comeau (Unix) |
—strict or -A |
Borland |
-A [20] |
Digital Mars |
-A |
[19] Versions of the Intel compiler for Linux prior to 9.0 used the option -strict_ansi. When using -strict-ansi or -strict_ansi, it may be necessary to enable Intel’s standard library, using the option -cxxlib-icc. [20] With the option -A, some of the standard headers from the STLPort library may fail to compile. |
Table 1-38. Enforcing strict conformance from your IDE
IDE |
Configuration |
---|---|
Visual C++ |
From your project’s property pages, go to Configuration Properties→ C/C++→ Language and set Disable Language Extensions, Treat wchar_t as Built-in Type, and Force Conformance in For Loop Scopes to Yes. |
Metrowerks |
From the Target Settings Window, go to Language Settings→ C/C++ Language and check ISO Template Parser, ANSI Strict, and ANSI Keywords Only. Make sure that the options Enable C++ Exceptions, Enable RTTI support, Enable bool Support, and Enable wchar_t Support are checked. |
C++Builder |
From Project Options, go to Advanced Compiler and check ANSI under Language Compliance. |
Dev-C++ |
See the entry for GCC in Table 1-37 and refer to Recipe 1.20. |
The C++ language was standardized in 1998 by the International Standards Organization (ISO); in the same year, the ISO standard was adopted by the American National Standards Institute (ANSI). In 2003, a second edition of the standard was approved; the second edition contained corrections and clarifications, but introduced no new language features. Work is currently underway on an updated version of the C++ standard that will contain some important new language features and an expanded standard library.
At the time the standard was approved in 1998, no compiler came close to meeting its requirements—though many were advertised as “ANSI-compliant.” Over the years, however, vendors have worked hard to bring their tools into conformance. As of September 2005, the latest versions of the GNU, Microsoft, Intel, Metrowerks, and Comeau compilers are all highly conformant. Comeau and Intel, with their support for exported templates, can now almost claim to be 100% conformant.[21]
No compiler is able to enforce perfect conformance to the standard, if that means refusing to compile any invalid program. This is not just because no compiler is 100% conformant: a more fundamental reason is that the C++ standard does not require a compiler to reject all invalid programs. There is a carefully delimited set of circumstances in which a compiler is required to issue a diagnostic, indicating an ill-formed program; for many invalid programs, however, no diagnostic is required. These are the programs that invoke what the standard calls undefined behavior at runtime. And even when a diagnostic is required, a compiler is permitted to issue the diagnostic and continue with compilation, possibly leading to the successful creation of an executable or library.
The main reason that compilers are not required to reject all nonconforming programs is that in many cases nonconformance is computationally difficult—or even impossible—to detect. Another reason, discussed later, is that nonconforming programs are sometimes useful.
I recommend that you use your compiler’s strict conformance option as often as you can. There are some cases where it may not be appropriate, however; to better understand this, let’s look at several varieties of nonconforming code.
First, there is code that was legal in an early dialect of C++, before the language
was standardized. For example, in the early days of C++, the scope of a variable declared
in the initializer of a for
loop extended to the end of
the block containing the loop:
// WARNING: invalid code! int main() { for (int i = 0; i < 10; ++i) ; int j = i; // j == 10 }
This is not permitted by the standard, and offers no advantage over the standard scoping rules. The need to compile code like the above should arise only when maintaining legacy applications.
Another category of nonconforming code is code that uses experimental language
extensions that might eventually be incorporated into the C++ standard. For example, many
compilers provide an integral type long long
guaranteed
to have a size of at least 64 bits. As another example, several compilers provide a
built-in operator typeof
, with the same syntax as the
sizeof
operator, which returns the type of an
expression. Both of these features are likely to appear in the next version of the C++
standard, although the spelling of typeof
is expected
to change, probably to decltype
.
Be very careful before using an extension like this: before you know it, you may have to port your code to a platform that does not implement the extension, or that implements it with different semantics.
A third category of nonconforming code is code that makes use of platform-specific
language extensions necessary to take advantage of operating system features. The
attributes _ _declspec(dllexport)
and _ _declspec(dllimport)
, for building dynamic libraries on
Windows, and the attributes _ _stdcall
, _ _fastcall
and _ _cdecl
,
for representing Windows calling conventions, fall into this category. Although these are
language extensions, most Windows compilers will accept code containing them even in their
strict-conformance mode.
A final category of nonconforming code is code that violates the C++ standard but is perfectly valid according to some other useful standard. A prime example of such a standard is C++/CLI, which is currently in the final stages of standardization by the ECMA. C++/CLI is an extension to C++ that constitutes the C++ interface to the Command Language Infrastructure, the core of Microsoft’s .NET Framework. When compiling an application that uses certain C++/CLI extensions, a conforming C++ compiler is required to issue a diagnostic, but it’s free to generate a valid C++/CLI application, if it supports the C++/CLI standard.
If you need to compile nonconforming code, first see whether it will compile using the
options in Table 1-37 and Table 1-38. If not, some compilers offer a
range of more fine-grained conformance options that allow some nonconforming constructs to
compile but not others. For example, Comeau provides the option —long_long to specify that the type long
long
should be recognized. Finally, some compilers
provide options that cause them to report many violations of the standard as warnings
rather than errors. For example, GCC provides the option -pedantic for this purpose and
Comeau provides the options
—a, for Windows, and —strict_warnings or -a, for other
platforms.
[21] Why almost? Because even Comeau and Intel have some bugs, and the interpretations of some parts of the standard are disputed.
Get C++ Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.