Home
Mozilla: C++ Portability Guide
Contents
1. after the loop Declare local initialized aggregates as static Non portable example void A func_foo char foo_int 1 2 C This seemingly innocent piece of code will generate a loader error using the HP UX compiler linker If you really meant for the array to be static data say so Portable example void A func_foo http www cs umd edu users cml cstyle mozilla portable cpp html 8 of 15 10 1 2000 7 42 12 PM C portability guide static char f inti 21 2 TE Otherwise you can keep the array as an automatic and initialize by hand Portable example void A func_foo char foo_int 3 foo_int 0 XP_STRDUP 1 foo_int 1 XP_STRDUP 2 foo_int 2 XP_STRDUP C or something equally Byzantine 22 Expect complex inlines to be non portable Non portable example class FooClass int fooMethod char p if p 0 0 return 1 doSomething return 0 It s surprising but many C compilers do a very bad job of handling inline member functions Cfront based compilers like those on SCO and HP UX are prone to give up on all but the most simple inline functions with the error message sorry unimplemented Often times the source of this problem is an inline with multiple return statements The fix for this is to resolve the returns into a single point at the end of the function But t
2. Not all C compilers support the mut able keyword You ll have to use the fake this approach to cast away the constness of a data member void MyClass MyConstMethod const MyClass fakeThis NS_CONST_CAST MyClass this Treat mFoo as mutable fakeThis gt mFoo 99 Use nsCOMPtr in XPCOM code Mozilla has recently adopted the use of nsCOMPtr in XPCOM code See the nsCOMPtr User Manual for usage details Stuff that is good to do for C or C 1 Always use the nspr types for intrinsic types http Awww cs umd edu users cml cstyle mozilla portable cpp html 12 of 15 10 1 2000 7 42 12 PM C portability guide Always use the nspr types for intrinsic integer types The only exception to this rule is when writing machine dependent code that is called from xp code In this case you will probably need to bridge the type systems and cast from an nspr type to a native type Do not wrap include statements with an ifdef Do not wrap include statements with an ifdef The reason is that when the symbol is not defined other compiler symbols will not be defined and it will be hard to test the code on all platforms An example of what not to do Bad code example don t do this ifdef X finclude foo h fendif The exception to this rule is when you are including different system files for different machines In that case you may need to have a ifdef SYSTEM_X include include st
3. or large file size Be careful to limit the include depth of your header files as well as your file size 25 Use virtual declaration on all subclass virtual member functions Non portable example class A virtual void foobar char class B public A void foobar char j 7 Another drag In the class declarations above A foobar is declared as virtual C says that all implementations of void foobar char in subclasses will also be virtual once virtual always virtual This code is really fine but some compilers want the virtual declaration also used on overloaded functions of the virtual in subclasses If you don t do it you get warnings While this is not a hard error because this stuff tends to be in headers files you ll get so many warnings that s you ll go nuts Better to silence the compiler warnings by including the virtual declaration in the subclasses It s also better documentation Portable example class A virtual void foobar char class B public A virtual void foobar char hi 26 Always declare a copy constructor and assignment operator One feature of C that can be problematic is the use of copy constructors Because a class s copy constructor defines what it means to pass and return objects by value or if you prefer pass by value means call the copy constructor it s important to get this right There are times when the compiler will silently generate a call to a c
4. C file The first C compiler Cfront was in fact a very fancy preprocessor for a C compiler Cfront reads the C code and generates C code that would do the same thing C startup is slightly different to C startup for example static constructor functions must be called for C and Cfront implements this special startup by noticing the function called main converting it to something else like ___cpp__main adding another main that does the special C startup things and then calls the original function Of course for all this to work Cfront needs to see the main function hence main must be in a C file Most compilers lifted this restriction years ago and deal with the C special initialization duties as a linker issue But there are a few commercial compilers shipping that are still based on Cfront HP and SCO are examples http www cs umd edu users cml cstyle mozilla portable cpp html 3 of 15 10 1 2000 7 42 12 PM C portability guide 10 11 12 So the workaround is quite simple Make sure that main is in a C file On the Unix version of Mozilla we did this by adding a new C file which has only a few lines of code and calls the main main which is actually in a C file Use the common denominator between members of a C C compiler family For many of the compiler families we use the implementation of the C and C compilers are completely different sometimes this means that the
5. C portability guide mozilla org The Mozilla Organization At A Glance Feedback Get Involved Newsgroups License Terms Newsbot Developer Docs Roadmap Projects Ports Module Owners Hacking Get the Source Build It Testing Download Report A Bug Bugzilla Bug Writing Tools View Source Tree Status New Checkins Submit A Bug FAQ Search C portability guide version 0 7 by David Williams 27 March 1998 Updated and maintained by Scott Collins and Christopher Blizzard What follows is a set of rules guidelines and tips that we have found to be useful in making C code portable across many machines and compilers This information is the result of porting large amounts of code across about 25 different machines and at least a dozen different C compilers Some of these things will frustrate you and make you want to throw your hands up and say well that s just a stupid compiler if it doesn t do lt insert favorite C feature gt But this is the reality of portable code If you play by the rules your code will seamlessly work on all of the Mozilla platforms and will be easy to port to newer machines We will endeavor to keep the information up to date for example sometimes a new compiler revision will lift a restriction If you have updates on any of these tips more information more ideas please forward them to Christopher Blizzard or Scott Collins If you find code in Mozilla that vio
6. C code and C s type free name rules need to be applied But the __cplusplus pre processor macro is still defined that s seen by the pre processor not the compiler In the system header file the C code inside the ifdef __cplusplus block will be seen by the compiler now running in C mode Syntax Errors galore If instead the extern C was done in the header file the C functions can be correctly guarded leaving the systems header file out of the equation This works Portable example system h ifdef _ cplusplus optimization inline int sgr int x return x x endif header h include lt system h gt extern C int existingCfunction char file cpp include header h One more thing before we leave the extern C segment of the program Sometimes you re going to have toextern C system files This is because you need to include C system header files that do not have http Awww cs umd edu users cml cstyle mozilla portable cpp html 7 of 15 10 1 2000 7 42 12 PM C portability guide 20 21 extern C guarding themselves Most vendors have updated all their headers to support C but there are still a few out there that won t grok C You might have to do this only for some platforms not for others using ifdef SYSTEM_X The safest place todo extern C a system header file in fact the safest place to include a system header file is at the lowest place possible in the header f
7. Not doing this right now a 87 if a gt b have to check for the candy factor CORSE ae This is a bad idea because you always end up wanting to kill code blocks that include comments already No you can t rely on comments nesting properly That s far from portable You have to do something crazy like changing pairs to pairs You ll forget And don t try using ifdef NOTUSED the day you do that the next day someone will quietly start defining NOTUSED somewhere It s much better to block the code out witha if 0 endif pair and a good comment at the top Of course this kind of thing should always be a temporary thing unless the blocked out code fulfills some amazing documentation purpose Portable example int foo a b oc if 0 Not doing this right now a 87 if a gt b have to check for the candy factor CFF endif 7 Turn on warnings for your compiler and then write warning free code This might be the most important tip Beware lenient compilers What generates a warning on one platform will generate errors on another Turn warnings on Write warning free code It s good for you Revision History e 0 5 Initial Revision 3 27 1998 David Williams e 0 6 Added C Style casts and mutable entries 12 24 1998 Ramiro Estrugo 0 7 Added nsCOMPtr entry and mozillaZine resource link 12 02 1999 Ramiro Estrugo http Awww cs umd edu users cml cstyle m
8. atements should include only simple filenames Non portable example include directory filename h Mac compilers handle include path names in a different manner to other systems Consequently include statements should contain just simple file names Change the directories that the compiler searches to get the result you need but if you follow the Mozilla module and directory scheme this should not be required Portable example include filename h Macs complain about assignments in boolean expressions Another example of code that will generate warnings on a Mac Generates warnings code if a b c Macs don t like assignments in if statements even if you properly wrap them in parentheses More portable example a b if a c Every source file must have a unique name Non portable file tree feature_x private h X Cpp feature_y private h Y CPP For Mac compilers every has to have a unique name Don t assume that just because your file is only used locally that it s OK to use the same name as a header file elsewhere It s not ok Every filename must be different Portable file tree feature_x http www cs umd edu users cml cstyle mozilla portable cpp html 13 of 15 10 1 2000 7 42 12 PM C portability guide xprivate h X Cpp feature_y yprivate h Y CPP 6 Use if 0 rather than comments to temporarily kill blocks of code Non portable example int foo as b c
9. extra top level semi colons Don t do it Portable example int A foo C filename extension is cpp This one is another plain annoying problem What s the name of a C file file cpp file cc http www cs umd edu users cml cstyle mozilla portable cpp html 4 of 15 10 1 2000 7 42 12 PM C portability guide 13 14 15 16 17 18 file c file cxx file ct file C Most compilers could care less but some are very particular We have not been able to find one file extension which we can use on all the platforms we have ported Mozilla code to For no great reason we ve settled on file cpp probably because the first C code in Mozilla code was checked in with that extension Well it s done The extension we use is cpp This extension seems to make most compilers happy but there are some which do not like it On those systems we have to create a wrapper for the compiler see STRICT_CPLUSPLUS_SUFFIX in ns config rules mk and ns build which actually copies the file cpp file to another file with the correct extension compiles the new file then deletes it If in porting to a new system you have to do something like this make sure you use the 1ine directive so that the compiler generates debug information relative to the original cpp file Don t mix varargs and inlines Non portable example class FooBar void va_inline char p something bi The subject says it a
10. here are other constructs which will result in not implemented For this reason you ll see that most of the C code in Mozilla does not use inline functions We don t want to legislate inline functions away but you should be aware that there is some danger in using them so do so only when there is some measurable gain not just a random hope of performance win Maybe you should just not go there Portable example class FooClass int fooMethod char p int return_value if PLO NOM og return_value 1 else doSomething return_value 0 return return_value Or http Awww cs umd edu users cml cstyle mozilla portable cpp html 9 of 15 10 1 2000 7 42 12 PM C portability guide Portable example class FooClass int fooMethod char p int FooClass fooMethod char p if p 0 0 return i doSomething return 0 23 Don t use return statements that have an inline function in the return expression For the same reason as the previous tip don t use return statements that have an inline function in the return expression You ll get that same sorry unimplemented error Store the return value in a temporary then pass that back 24 Be careful with the include depth of files and file size Be careful with the include depth of files and file size The Microsoft Visual C 1 5 compiler will generate internal compiler errors if you have a large include depth
11. ile inclusion hierarchy That is push all this stuff down to the header files closer to the system code don t do this stuff in the mail header files Ideally the best place to do this is in the NSPR or XP header files which sit directly on the system code Be careful of the scoping of variables declared inside for statements Non portable example void A f00 for int i 0 i lt 10 i do something i might get referenced after the loop This is actually an issue that comes about because the C standard has changed over time The original C specification would scope the i as part of the outer block in this case function A foo The standard changed so that now the i in is scoped within the for block Most compilers use the new standard Some compilers for example HP UX still use the old standard Some other compilers for example gcc use the new rules but will tolerate the old If i was referenced later inthe for block gcc will allow the construct but give a warning about use of an obsolete binding So while the code above is valid it would become ambiguous if i was used later in the function It s probably better to be on the safe side and declare the iterator variable outside of the for loop Then you ll know what you are getting on all platforms Portable example void A f00 ante i for i 0 i lt 10 itt do something i might get referenced
12. lates any of these rules please report it as a bug You can use bonsai to find the author C portability rules Don t use C templates Don t use static constructors Don t use exceptions Don t use Run time Type Information Don t use namespace facility main must be in a C file Use the common denominator between members of a C C compiler family Don t put C comments in C code CON ANA WN S Don t put carriage returns in XP code Put a new line at end of file j i j Don t put extra top level semi colons in code 12 C filename extension is cpp 13 Don t mix varargs and inlines 14 Don t use initializer lists with objects 15 Always have a default constructor 16 Don t put constructors in header files 17 Be careful with inner classes 18 Be careful of variable declarations that require construction or initialization 19 Make header files compatible with C and C 20 Be careful of the scoping of variables declared inside for statements 21 Declare local initialized aggregates as static 22 Expect complex inlines to be non portable http www cs umd edu users cml cstyle mozilla portable cpp html 1 of 15 10 1 2000 7 42 12 PM C portability guide 23 24 25 26 21 28 29 30 31 32 Don t use return statements that have an inline function in the re
13. ll varargs and inline functions do not seem to mix very well If you must use varargs which can cause portability problems on their own then ensure that the vararg member function is a non inline function Portable example foobar h class FooBar void va_non_inline char p foobar cpp void FooBar va_non_inline char p something Don t use initializer lists with objects Non portable example FooClass myFoo 10 20 Some compilers won t allow this syntax for objects HP UX won t actually only some will allow it So don t do it Again use a wrapper function see Don t use static constructors Always have a default constructor Always have a default constructor even if it doesn t make sense in terms of the object structure hierarchy HP UX will barf on statically initialized objects that don t have default constructors Don t put constructors in header files The Visual C 1 5 compiler for windows is really flaky and putting constructors into the headers seems to be one of the causes of mysterious internal compiler errors Be careful with inner classes Some compilers HP UX generally require that types classes enums etc declared inside of another class should be referred to with their fully scoped form e g Foo kListMaxLen versus kListMaxLen Be careful of variable declarations that require construction or initialization Non portable example http Awww c
14. opy constructor that maybe you do not want For example when a you pass an object by value as a function parameter a temporary copy is made which gets passed then destroyed on return from the function Maybe http Awww cs umd edu users cml cstyle mozilla portable cpp html 10 of 15 10 1 2000 7 42 12 PM C portability guide you don t want this to happen maybe you d always like instances of your class to be passed by reference If you do not define a copy constructor the C compiler will generate one for you the default copy constructor and this automatically generated copy constructor might well suck So you have a situation where the compiler is going to silently generate calls to a piece of code that might not be the greatest code for the job it may be wrong Ok you say no problem I know when I m calling the copy constructor and I know I m not doing it But what about other people using your class The safe bet is to do one of two things if you want your class to support pass by value then write a good copy constructor for your class If you see no reason to support pass by value on your class then you should explicitly prohibit this don t let the compiler s default copy constructor do it for you The way to enforce your policy is to declare the copy constructor as private and not supply a definition While your at it do the same for the assignment operator used for assignment of objects of the same class Example clas
15. ozilla portable cpp html 14 of 15 10 1 2000 7 42 12 PM C portability guide Further reading Here are some books and pages which provide further good advice on how to write portable C code Oo Scott Meyers Effective C 50 Specific Ways to Improve Your Programs and Designs O Robert B Murray C Strategies and Tactics o mozillaZine has a list of books on C Anti C OOP and other buzzwords This list was compiled from the suggestions of Mozilla developers o others Copyright 1998 Netscape Communications Corporation Copyright 1998 2000 The Mozilla Organization Last modified July 5 2000 http www cs umd edu users cml cstyle mozilla portable cpp html 15 of 15 10 1 2000 7 42 12 PM
16. re are things you can do in the C language that you cannot do in the C language on the same machine One example is the long long type On some systems IBM s compiler used to be one but I think it s better now the C compiler supports long long while the C compiler does not This can make porting a pain as often times these types are in header files shared between C and C files The only thing you can do is to go with the common denominator that both compilers support In the special case of long long we developed a set of macros for supporting 64 bit integers when the long long type is not available We have to use these macros if either the C or the C compiler does not support the special 64 bit type Don t put C comments in C code The quickest way to raise the blood pressure of a Netscape Unix engineer is to put C comments comments into C files Yes this might work on your Microsoft Visual C compiler but it s wrong and is not supported by the vast majority of C compilers in the world Just do not go there Many header files will be included by C files and included by C files We think it s a good idea to apply this same rule to those headers Don t put C comments in header files included in C files You might argue that you could use C style comments inside ifdef __ cplusplus blocks but we are not convinced that is always going to work some compilers have weird interactions between comment stripping and pre p
17. rocessing and it hardly seems worth the effort Just stick to C style comments for any header file that is ever likely to be included by a C file Don t put carriage returns in XP code While this is not specific to C we have seen this as more of an issue with C compilers see Use the common denominator between members of a C C compiler family On unix systems the standard end of line character is new line n The standard on many PC editors is carriage return r The PC compilers seem to be happy either way but some Unix compilers just choke when they see a carriage return they do not recognize the character as white space So we have a rule that you cannot check in carriage returns into any cross platform code This rule is not enforced on the Windows front end code as that code is only ever compiled on a PC The Mac compilers seem to be happy either way but the same rule applies as for the PC no carriage returns in cross platform code Put a new line at end of file Not having a new line char at end of file breaks some compilers Solaris Don t put extra top level semi colons in code Non portable example int A f 00 J This is another problem that seems to show up more on C than C code This is problem really a bit of a drag That extra little semi colon at the end of the function is ignored by most compilers but it makes some compilers very unhappy IBM s AIX compiler doesn t like
18. s foo private These are not supported and are not implemented foo const foo amp x foo amp operator const foo amp x 7 When you do this you ensure that code that implicitly calls the copy constructor will not compile and link That way nothing happens in the dark When a user s code won t compile they ll see that they were passing by value when they meant to pass by reference oops 27 Be careful of overloaded methods with like signatures It s best to avoid overloading methods when the type signature of the methods differs only by 1 abstract type e g PR_Int 32 or int 32 What you will find as you move that code to different platforms is suddenly on the Foo2000 compiler your overloaded methods will have the same type signature 28 Type scalar constants to avoid unexpected ambiguities Non portable code class FooClass having such similar signatures is a bad idea in the first place void doit long void doit short hi void B foo FooClass xyz xyz gt doit 45 Be sure to type your scalar constants e g PR_INT32 10 or 10L Otherwise you can produce ambiguous function calls which potentially could resolve to multiple methods particularly if you haven t followed 2 above Not all of the compilers will flag ambiguous method calls Portable code class FooClass having such similar signatures is a bad idea in the first place void doit long void doit
19. s umd edu users cml cstyle mozilla portable cpp html 5 of 15 10 1 2000 7 42 12 PM C portability guide void Ax foo int g switch c case FOOBAR_1 XyzClass buf 100 stuff break Be careful with variable placement around if blocks and switch statements Some compilers HP UX require that any variable requiring a constructor initializer to be run needs to be at the start of the method it won t compile code when a variable is declared inside a switch statement and needs a default constructor to run Portable example void A foo int c XyzClass buf 100 switch c case FOOBAR_1 stuff break 19 Make header files compatible with C and C Non portable example oldCheader h int existingCfunction char int anotherExistingCfunction char oldCfile c include oldCheader h new file cpp extern C include oldCheader h If you make new header files with exposed C interfaces make the header files work correctly when they are included by both C and C files If you start including an existing C header in new C files fix the C header file to support C as well as C don t just extern C the old header file Do this Portable example oldCheader h ifdef _ cplusplus extern C endif int existingCfunction char int anotherExistingCfunction char ifdef _ cplusplus endif http Awww cs umd edu users cml cs
20. same result There is a an exception to this rule nsCOMPtr However this does not mean Open Season for template code The Don t use C templates rule still applies nsCOMPtr is allowed because the authors spent a lot of time making sure their use of templates does not break poor compilers It is very likely that other simple template code will break some poor compilers which we need to support Don t use static constructors Non portable example FooBarClass static_object 87 92 void bar if static_object count gt 15 http Awww cs umd edu users cml cstyle mozilla portable cpp html 2 of 15 10 1 2000 7 42 12 PM C portability guide Static constructors don t work reliably either A static initialized object is an object which is instanciated at startup time just before main is called Usually there are two components to these objects First there is the data segment which is static data loaded into the global data segment of the program The second part is a initializer function that is called by the loader before main is called We ve found that many compilers do not reliably implement the initializer function So you get the object data but it is never initialized One workaround for this limitation is to write a wrapper function that creates a single instance of an object and replace all references to the static initialized object with a call to the wrapper function Portable e
21. short hi void http Awww cs umd edu users cml cstyle mozilla portable cpp html 11 of 15 10 1 2000 7 42 12 PM C portability guide 29 30 31 32 B foo FooClass xyz xyz gt doit 45L Type scalar constants to avoid unexpected ambiguities Some platforms e g Linux have native definitions of types like Bool which sometimes conflict with definitions in XP code Always use PRBool PR_TRUE PR_FALSE or XP_Bool TRUE FALSE Use macros for C style casts Not all C compilers support C style casts static_cast lt type gt expression C style type expression C style The header nscore h defines portable cast macros that use C style casts on compilers that support them and regualar casts otherwise These macros are defined as follows define NS_STATIC_CAST __type __ptr static_cast lt __type gt __ptr define NS_CONST_CAST __type __ptr const_cast lt __type gt __ptr define NS_REINTERPRET_CAST __type __ptr reinterpret_cast lt __type gt __ptr Note that the semantics of dynamic_cast cannot be duplicated so we dont use it See Chris Waterson s detailed explanation on why this is so Example Instead of foo_t x static_cast lt foo_t gt client_data bar_t nonConstX const_cast lt bar_t gt this You should use foo_t x NS_STATIC_CAST foo_t client_data bar_t nonConstX NS_CONST_CAST bar_t this Don t use mutable
22. turn expression Be careful with the include depth of files and file size Use virtual declaration on all subclass virtual member functions Always declare a copy constructor and assignment operator Be careful of overloaded methods with like signatures Type scalar constants to avoid unexpected ambiguities Always use PRBool or XP_Bool for boolean variables in XP code Use macros for C style casts Don t use mutable Use nsCOMPtr in XPCOM code Stuff that is good to do for C or C YU HRDaAF WN Always use the nspr types for intrinsic types Do not wrap include statements with an ifdef include statements should include only simple filenames Macs complain about assignments in boolean expressions Every source file must have a unique name Use if 0 rather than comments to temporarily kill blocks of code Turn on warnings for your compiler and then write warning free code Revision History Further Reading C portability rules 1 Don t use C templates Don t use the C template feature This feature is still not implemented by all compilers and even when it is implemented there is great variation Most of the interesting things that you would want to do with templates type safe container classes etc can be implemented with macros and casting even though you do lose the type safety pity Often times subclassing can easily achieve the
23. tyle mozilla portable cpp html 6 of 15 10 1 2000 7 42 12 PM C portability guide oldCfile c include oldCheader h new file cpp include oldCheader h There are number of reasons for doing this other than just good style For one thing you are making life easier for everyone else doing the work in one common place the header file instead of all the C files that include it Also by making the C header safe for C you document that hey this file is now being included in C That s a good thing You also avoid a big portability nightmare that is nasty to fix Some systems include C in system header files that are designed to be included by C or C Not just extern C guarding but actual C code usually in the form of inline functions that serve as optimizations While we question the wisdom of vendors doing this there is nothing we can do about it Changing system header files is not a path we wish to take Anyway so why is this a problem Take for example the following code fragment Non portable example system h ifdef _ cplusplus optimization inline int sgr int x return x x endif header h include lt system h gt int existingCfunction char file cpp extern C include header h What s going to happen When the C compiler finds the extern C declaration in file cpp it will switch dialects to C because it s assumed all the code inside is
24. xample static FooBarClass static_object FooBarClass getStaticObject if static_object static_object new FooBarClass 87 92 return static_object void bar if getStaticObject gt count gt 15 3 Don t use exceptions Exceptions are another C feature which is not very widely implemented and as such their use is not portable C code Don t use them Unfortunately there is no good workaround that produces similar functionality One exception to this rule don t say it is that it s probably ok and may be necessary to use exceptions in some machine specific code If you do use exceptions in machine specific code you must catch all exceptions there because you can t throw the exception across XP cross platform code Don t use Run time Type Information Run time type information RTTD is a relatively new C feature and not supported in many compilers Don t use it If you need runtime typing you can achieve a similar result by adding a classOf virtual member function to the base class of your hierarchy and overriding that member function in each subclass If classOf returns a unique value for each class in the hierarchy you ll be able to do type comparisons at runtime Don t use namespace facility Support of namespaces through the namespace and using keywords is a relatively new C feature and not supported in many compilers Don t use it 6 main must be in a
Download Pdf Manuals
Related Search
Related Contents
User manual - SupplyHouse.com 92108 ES Hierro directo Copyright © All rights reserved.
Failed to retrieve file