File: cs_273.html

package info (click to toggle)
crystalspace 0.94-20020412-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 62,276 kB
  • ctags: 52,843
  • sloc: cpp: 274,783; ansic: 6,608; perl: 6,276; objc: 3,952; asm: 2,942; python: 2,354; php: 542; pascal: 530; sh: 430; makefile: 370; awk: 193
file content (352 lines) | stat: -rw-r--r-- 14,896 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Created by texi2html 1.64 -->
<!-- 
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
            Karl Berry  <karl@freefriends.org>
            Olaf Bachmann <obachman@mathematik.uni-kl.de>
            and many others.
Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
 
-->
<HTML>
<HEAD>
<TITLE>Crystal Space: Portability</TITLE>

<META NAME="description" CONTENT="Crystal Space: Portability">
<META NAME="keywords" CONTENT="Crystal Space: Portability">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META NAME="Generator" CONTENT="texi2html 1.64">

</HEAD>

<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">

<A NAME="SEC644"></A>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_272.html#SEC638"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_274.html#SEC645"> &gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_271.html#SEC637"> &lt;&lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_271.html#SEC637"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_277.html#SEC648"> &gt;&gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<HR SIZE=1>
<H2> 9.2 Portability </H2>
<!--docid::SEC644::-->
<P>

<EM>Written by Eric Sunshine, <A HREF="mailto:sunshine@sunshineco.com">sunshine@sunshineco.com</A>, with
contributions by others.</EM>
</P><P>

Crystal Space is a highly portable cross-platform 3D engine and toolkit.  As a
contributor to the project, you should familiarize yourself with the issues
discussed in this section in order to ensure maximum portability of code which
you write and resources which you create.
</P><P>

<OL>
<LI>
<EM>Endian-ness</EM>
<P>

Beware of code that is endian-specific.  To facilitate writing portable code,
key off of the `<SAMP>CS_BIG_ENDIAN</SAMP>' or `<SAMP>CS_LITTLE_ENDIAN</SAMP>' macros if
necessary.
</P><P>

Avoid casting a `<SAMP>long*</SAMP>' or `<SAMP>int*</SAMP>' to a `<SAMP>short*</SAMP>' or `<SAMP>char*</SAMP>'
as a slick way of checking the value of a particular sub-byte of the number
since this trick will fail on platforms with different endian-ness.  In other
words, given the declaration `<SAMP>long n = 1</SAMP>', and the expression `<SAMP>short
p = *((short*)&#38;n)</SAMP>', on a little-endian platform, `<SAMP>p</SAMP>' will equal 1, but on
a big-endian platform, `<SAMP>p</SAMP>' will equal 0.
</P><P>

Avoid using C "unions" to represent bit-sets since they can result in
endian-related problems if improperly used or stored as persistent data.
Using bit-masks is a much better and far more portable solution.
</P><P>

Beware of reading and writing data to binary format files and sending such
information over the network.  Unless special care is taken to ensure
portability, these files and network related facilities will suffer
endian-related problems.  Use the network functions <CODE>ntohl()</CODE>,
<CODE>ntohs()</CODE>, <CODE>htonl()</CODE>, and <CODE>htons()</CODE> to convert numbers to
canonical format before transmitting them over the network.  You can also make
use of the Crystal Space endian-related converion functions found in
`<TT>CS/include/cssys/csendian.h</TT>'.
</P><P>

<LI>
<EM>Data Alignment</EM>
<P>

Some platforms require data values to be strictly aligned in memory.  For
instance, some processors can not access a `<SAMP>long</SAMP>' value at an odd memory
address or at an address which is not a multiple of four (which is the size in
bytes of the `<SAMP>long</SAMP>' data type).  In such cases, the program may crash.
Other processors may be able to access misaligned values, but at grealy
reduced speed, which can slow down program execution significantly if done
frequently enough.
</P><P>

In most cases, the compiler ensures that values are properly aligned for the
given processor, but this problem can crop up when reading byte-streams from
external sources such as binary files or network connections.  In such cases,
it is up to you to ensure the proper alignment of the data before accessing
it.
</P><P>

For instance, if you are reading elements from a byte-stream and the next
element to be read is a `<SAMP>long</SAMP>', then the following code to extract the
value is <EM>incorrect</EM> and <EM>non-portable</EM> since it does not ensure
that the data is aligned properly for `<SAMP>long</SAMP>' access:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>long extract_long(unsigned char const* stream)
{
  return *((long*)stream);
}
</pre></td></tr></table></P><P>

The correct way to code this example would be as follows:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>long extract_long(unsigned char const* stream)
{
  long n;
  memcpy(&#38;n, stream, sizeof(n));
  return n;
}
</pre></td></tr></table></P><P>

<LI>
<EM>Floating Points</EM>
<P>

Depending upon the accuracy and representation of floating point values on
some platforms, a number may successfully compare to (and equal) 0.0 on one
platform or processor but fail on another.  In order to avoid such problems,
compare numbers to a small value such as `<SAMP>EPSILON</SAMP>'.  In other words, if
`<SAMP>EPSILON</SAMP>' is defined as a very small value, use `<SAMP>(val &#60; EPSILON)</SAMP>'
rather than `<SAMP>(val == 0.0)</SAMP>'.
</P><P>

As a corollary.  when comparing two floating point values, employ the
`<SAMP>EPSILON</SAMP>' trick to ensure that they compare properly over a wide variety
of platforms.  In other words, instead of `<SAMP>(float1 &#60; float2)</SAMP>', use
`<SAMP>(float1 &#60; float2 + EPSILON)</SAMP>'.
</P><P>

<LI>
<EM>Scope of `<SAMP>for</SAMP>' Statements</EM>
<P>

Some compilers do not properly scope a variable declared in a <CODE>for(;;)</CODE>
statement to the loop itself.  In other words, some compilers treat the
following code:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>for (int i = 0; <small>...</small>) <small>...</small>
</pre></td></tr></table></P><P>

As though `<SAMP>i</SAMP>' was declared outside of the `<SAMP>for</SAMP>' statement, as in:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>int i;
for (i = 0; <small>...</small>) <small>...</small>
</pre></td></tr></table></P><P>

This can be a problem when several `<SAMP>for</SAMP>' loops exists at the same scoping
level in a single block since some compilers will complain that `<SAMP>i</SAMP>' is
being redeclared by all `<SAMP>for</SAMP>' loops following the first one.  In other
words, the following code will generate a "variable redeclaration" warning
with some compilers:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>for (int i = 0; <small>...</small>) <small>...</small>
<small>...</small> other code <small>...</small>
for (int i = 5; <small>...</small>) <small>...</small>
</pre></td></tr></table></P><P>

In cases where the variable appears in only a single `<SAMP>for</SAMP>' loop, declaring
it directly in the `<SAMP>for</SAMP>' statement is perfectly safe, but in cases where
many such loops may want to use the same variable name, the variable should
be declared once outside of all loops, as in the following example:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>int i;
for (i = 0; <small>...</small>) <small>...</small>
<small>...</small> other code <small>...</small>
for (i = 5; <small>...</small>) <small>...</small>
</pre></td></tr></table></P><P>

The Microsoft Visual C++ compiler is known to suffer from this problem,
however most modern C++ compilers properly scope variables declared in the
`<SAMP>for</SAMP>' statement.
</P><P>

<LI>
<EM>Avoid Global Objects With Constructors in Plug-In Modules</EM>
<P>

Avoid placing global objects which require automatic construction in
dynamically loaded libraries (plug-in modules).  Some platforms fail to call
the object's constructor at the time the library is loaded.  Therefore it is
unsafe to rely on such objects.
</P><P>

<LI>
<EM>Avoid Initiailizing Global Variables via Functions in Plug-In Modules</EM>
<P>

Avoid initiailizing global variables within a plug-in module via function
call.  In other words, in the following example, the function <CODE>foo()</CODE>
should not rely upon the variable `<SAMP>angle</SAMP>' as having been properly
initialized, assuming that this code fragment appears in a plug-in module.
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>static float angle = cos(0.23);
void foo() { printf("angle=%g\n", angle); }
</pre></td></tr></table></P><P>

Instead, you should arrange for such variables to be initialized manually by
some other mechanism.  Here is one possible (though not ideal) way to ensure
that `<SAMP>angle</SAMP>' is initiailized before it is accessed.
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>static float angle = 0;
void foo()
{
  static bool angle_ok = false;
  if (!angle_ok)
  {
    angle = cos(0.23);
    angle_ok = true;
  }
  printf("angle=%g\n", angle);
}
</pre></td></tr></table></P><P>

An even better solution is to utilize the initialization hooks provided by the
SCF system to initialize global variables at the time that the plug-in
module is loaded.  See section <A HREF="cs_134.html#SEC297">6.4 Shared Class Facility (SCF)</A>.
</P><P>

<LI>
<EM>DOS Filename Restrictions</EM>
<P>

Use DOS-style 8.3 filenames for files which are shared by all platforms
which run Crystal Space.  This allows the project to support DOS in
addition to platforms with less restrictive filenames.  Platform-specific
files (not intended for DOS) need not follow this restriction.
</P><P>

<LI>
<EM>Pathname Syntax</EM>
<P>

Pathname syntax varies widely from platform to platform.  For instance, a
Unix-style pathname such as `<TT>/mnt/home/zoop.c</TT>' might appear as
`<TT>C:\home\zoop.c</TT>' on DOS and Windows, and `<TT>vol:home:zoop.c</TT>' on
Macintosh.
</P><P>

When programming you should always use Unix-style pathname syntax in your
<CODE>#include</CODE> directives; that is, always use the forward slash `<SAMP>/</SAMP>', as
in <CODE>#include "csutil/scf.h"</CODE>.  The forward slash is understood by
compilers on all platforms including Unix, Windows, and Macintosh.  Never use
`<SAMP>\</SAMP>' or `<SAMP>:</SAMP>' in filenames mentioned by an <CODE>#include</CODE> directive.
Even though your Windows or Macintosh compiler might accept these characters,
the Unix compilers will not.  The obvious exception to this rule is for source
files which are intended only for a specific platform.  Such files may use the
prohibited characters, but in general there is no reason to do so.
</P><P>

At the application level, when writing a program or library which utilizes
Crystal Space you should make use of the VFS facility which provides a
unified way of referring to files by hiding platform-specific pathname syntax
details.  Under VFS's unified naming scheme, all pathnames use the
Unix-style syntax and VFS translates such pathnames to a form appropriate
for the host platform.  See section <A HREF="cs_161.html#SEC340">7.2 Virtual File System (VFS)</A>.
</P><P>

<LI>
<EM>Filesystem Case Sensitivity</EM>
<P>

Some operating systems have case sensitive filenames, whereas others do not.
Undesirable things happen if you capitalize a file one way in an
<CODE>#include</CODE> directive and a different way for the actual filename.  This
problem may not even be apparent on your platform if you are using a
case-insensitive file system such as DOS, Windows, or Macintosh (HFS).  In
general, it is preferable to use entirely lower-case filenames for files which
are shared between ports.
</P><P>

<STRONG>Warning</STRONG>: `<TT>WinCVS</TT>' has been reported to botch capitalization of
files.  Please be aware of this potential problem.
</P><P>

<LI>
<EM>Makefiles and Project Files</EM>
<P>

Some platforms use custom project files, whereas other platforms use the
Crystal Space makefile system.  If you change a makefile and then change the
code so that it depends on this change, ports for other platforms will
probably break.  This may be unavoidable to some extent, but try to minimize
the breakage.  For example, wrap the dependent code in an <CODE>#ifdef</CODE> and
check for operating systems that <EM>do</EM> support the change.  This will
allow other systems to continue to work without your change.  After committing
your change to the CVS repository, be sure to inform port maintainers
that their projects may need to be updated in order to support your
modifications.
</P><P>

<LI>
<EM>Ensuring Rendering</EM>
<P>

Some renderers and video drivers depend on the <CODE>BeginDraw()</CODE> and
<CODE>FinishDraw()</CODE> calls to `<SAMP>iGraphics3D</SAMP>' or `<SAMP>iGraphics2D</SAMP>'.  Thus
every <CODE>BeginDraw()</CODE> must be followed by a <CODE>FinishDraw()</CODE> or nothing
will be rendered.  Microsoft's DirectX renderer is known to have this
requirement, so be sure to follow this guideline for maximum portability.
</P><P>

<LI>
<EM>Avoid Templates</EM>
<P>

Some compilers don't support templates, so you should not use them.
</OL>
<A NAME="Coding Style"></A>
<HR SIZE=1>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_272.html#SEC638"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_274.html#SEC645"> &gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_271.html#SEC637"> &lt;&lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_271.html#SEC637"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_277.html#SEC648"> &gt;&gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<BR>  
<FONT SIZE="-1">
This document was generated

using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>

</BODY>
</HTML>