Audacity 3.2.0
Cross Platform Coding Tips

Guidelines for making the code compile and work on all supported platforms.

#pragma once

The following is not supported under gcc 2.x:

// WRONG
#pragma once

Instead use the traditional:

#ifndef __AUDACITY_HEADER_FILE_NAME__
#define __AUDACITY_HEADER_FILE_NAME__
// your header file contents goes here.
#endif

Unicode strings

Audacity code is translated, and it may be built in Unicode versions.
For this reason all strings should be wrapped like this:

// for strings which are not translated
mMyFirstString = wxT("some untranslated string");
// for strings which should be translated
mMySecondString = _("some translatable string");
wxT("CloseDown"))
#define _(s)
Definition: Internat.h:73

In some cases you need to give hints to a translator about how a string should be translated. Do so as follows:

/* i18n-hint: One-letter abbreviation for Left, in VU Meter */
mLeftText = _("L");
/* i18n-hint: One-letter abbreviation for Right, in VU Meter */
mRightText = _("R");

Very long strings can be wrapped across multiple lines, as follows:

// For untranslated strings:
wxT("This is a long untranslated string ")
wxT("which spans several lines ")
wxT("and works in Unicode builds too")
// For translated strings:
_("This is a long translated string "
wxT("which spans several lines ")
wxT("and works in Unicode builds too"))

Notice that in the translated example, all bar the first substring are contained within a wxT().

Constructors as Arguments

Don't write code like this:

// WRONG
// Now call OnSampleRateChange to update the values.
OnSampleRateChange( wxCommandEvent() );

Whilst it is fine under MSVC it will cause a problem under gcc as the constructor is a temporary object which will be optimised away.

Instead use:

// Now call OnSampleRateChange to update the values.
wxCommandEvent e;
OnSampleRateChange( e );

Header Files

Windows systems are not case sensitive, whilst Linux systems are. You therefore need to take care in capitalisation, e.g:

Class Names in Classes

Microsoft Visual C++ allows you to write code like this in a header file:

// WRONG
class MyClass
{
public:
int MyClass::SomeFunction();
//... other stuff

For portability, the 'MyClass::' prefix should be left out.

Using wxString in Format

Don't write code like this:

wxString Message( wxT("Hello" ));
// WRONG
wxString Temp = wxString::Format(wxT("Your said %s in your message"), Message );
TranslatableString Message(unsigned trackCount)

Although MSVC won't complain even in Unicode mode, it generates a warning under gcc. Instead you need:

wxString Message( wxT("Hello" ));
wxString Temp = wxString::Format(wxT("Your said %s in your message"), Message.c_str() );

Forward Declared Enums

Microsoft Visual C++ allows you to write code like this in a header file:

// WRONG
enum MyEnum;

That is, you can forward declare an enum just as you can forward declare a class. This is not portable. The alternative is to include a header file containing the full enum definition.

#include "MyEnum.h"