19.10.2012 Views

Designing and Building Portable Systems in C++ - Applied Informatics

Designing and Building Portable Systems in C++ - Applied Informatics

Designing and Building Portable Systems in C++ - Applied Informatics

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

This is what one would <strong>in</strong>tuitively expect, assum<strong>in</strong>g left-to-right argument evaluation.<br />

Compiled with HP ANSI <strong>C++</strong> A.03.57 on HP-UX 11.11, the result is the same. However,<br />

when compiled with Compaq <strong>C++</strong> 6.5 on HP Tru64 5.1, the program yields:<br />

a = 0, b = 0, c = 0<br />

which may be surpris<strong>in</strong>g. However, with regard to the <strong>C++</strong> st<strong>and</strong>ard, both results are correct.<br />

Firstly, the compiler is free to evaluate the function arguments <strong>in</strong> any order it likes – from left<br />

to right, from right to left, <strong>in</strong> order of decreas<strong>in</strong>g expression complexity, or even <strong>in</strong> r<strong>and</strong>om<br />

order. Secondly, the compiler is free to delay the <strong>in</strong>crement operation until all arguments have<br />

been evaluated.<br />

2.1.3 Language Extensions <strong>and</strong> Syntactical Freedom<br />

Especially Microsoft Visual <strong>C++</strong> has many “features” that make writ<strong>in</strong>g portable code<br />

unnecessarily hard for developers not pay<strong>in</strong>g enough attention to correct syntax. There is a<br />

compiler sett<strong>in</strong>g to turn off language extensions, but with this sett<strong>in</strong>g enabled, one can no<br />

longer use the W<strong>in</strong>dows Platform SDK, as its header files rely on non-st<strong>and</strong>ard language<br />

features. The most common problem cases are presented below.<br />

Method declarations<br />

The follow<strong>in</strong>g class def<strong>in</strong>ition is valid <strong>in</strong> Microsoft Visual <strong>C++</strong>, but causes errors on<br />

st<strong>and</strong>ards conformant compilers.<br />

Class A<br />

{<br />

void A::m();<br />

};<br />

In this example, the class name is part of the method declaration, which is both redundant <strong>and</strong><br />

not allowed by the st<strong>and</strong>ard. Mistakes of this k<strong>in</strong>d happen very easily if a class is extended<br />

with a new method. The developer starts by implement<strong>in</strong>g the new method <strong>in</strong> the<br />

implementation file, <strong>and</strong> then adds the correspond<strong>in</strong>g method declaration to the header file by<br />

copy-<strong>and</strong>-paste, forgett<strong>in</strong>g to remove the class scope from the declaration. The code compiles<br />

f<strong>in</strong>e with Microsoft Visual <strong>C++</strong>, but compilers that are more str<strong>in</strong>gent will produce error<br />

messages when be<strong>in</strong>g given such code.<br />

Po<strong>in</strong>ters to members<br />

Microsoft Visual <strong>C++</strong> allows a simplified syntax for pass<strong>in</strong>g po<strong>in</strong>ters to member functions.<br />

The follow<strong>in</strong>g class declaration def<strong>in</strong>es a po<strong>in</strong>ter to a method of B tak<strong>in</strong>g no arguments, as<br />

well as methods us<strong>in</strong>g this po<strong>in</strong>ter type.<br />

Class B<br />

{<br />

public:<br />

typedef void (B::*M)(); // po<strong>in</strong>ter to a method of B tak<strong>in</strong>g no<br />

args<br />

void <strong>in</strong>voke(M m);<br />

void do();<br />

void test();<br />

};<br />

The methods <strong>in</strong>voke() <strong>and</strong> do() can be implemented as follows:<br />

void B::<strong>in</strong>voke(B::M m)<br />

{<br />

(this->*m)();<br />

}<br />

5

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!