converting managed languages to c++

21
Dmitri Nesteruk JetBrains

Upload: dmitri-nesteruk

Post on 15-Jul-2015

85 views

Category:

Technology


0 download

TRANSCRIPT

Dmitri NesterukJetBrains

Managed language = C#, Java, D etc.GC (garbage collector), Unicode, …

Unmanaged languageSomething that compiles to native codeMore control, less safetyC/C++, VHDL, etc.

PerformanceStop-the-world GCLow-level control (e.g., SIMD)Collections (containers), multithreading

Defense against reverse-engineeringC#, Java are easy to decompile

Hardware supportCUDA, Xeon Phi

Portability (surprise!)Sudden desire to write everything in С++

Lex the source codeBuild ASTResolve symbolsTraverse the tree, translating it to a different languagePerfect translation is (of course) impossible

Translate syntax with fidelityFill the gaps in what’s missing

Replace equivalent constructsList<> vector<>

Handle cases where 1-to-1 mapping is impossible

Integral typesUse types from <cstdint>int int32_t, byte uint8_t, etc.

float/double as-isExtended precision types (System.Decimal)

Need external libs

Slightly different init rules

Unicode Most LoB apps do not absolutely require Unicode (nice to have)

Relatively safe option: string std::wstringchar wchar_tSlightly more careless option: string/char

A completely safe solution has to allow strings to be nullptrI.e., you either use char* or option<string>Expensive, tedious, just use myString.empty()

Unicode in source (identifiers, literals, …) won’t work

class Person{string name;int age;

}

class Person { std::string name;int32_t age;

public:Person();

};

Managed languagesGive types default valuesAllow initialization right in the declaration

In both cases, initialization happens in the (generated) ctorIn C++, types don’t have default values. So we are forced to make a constructor ourselves

Property = field+getter+setterCan be read or write-onlyCan be automatic

Name of field not specified explicitlyOffers no benefit over a field in C++

Can have an inline initializerMore ctor abuse

Two options hereGetXxx/SetXxx (safe, tedious)__declspec(property)(not C++ standard, but nicer)

int age;public int Age{get { return age; }set { age = value; }

}

// automaticpublic int Age{ get; set; }

__declspec(property(get = GetAge, put = PutAge)) int Age;

int GetAge() const { return age; }

void PutAge(int value) { … }

// laterPerson p;p.Age = 123; // calls PutAge()

Used in many places, e.g.:Handling UI interactionsProperty change notifications

C++ doesn’t have themBoost.SignalsTricky since event subscription is done with +=

And unsubscription with −=

template <typename T> class INotifyPropertyChanged{public:

signal<void(const T*, string)> PropertyChanged;

};

class Player : public INotifyPropertyChanged<Player>{int age;

public:__declspec(property(get = GetAge, put = PutAge)) int Age;int GetAge() const { return age; }void PutAge(int value){if (value == age) return;PropertyChanged(this, "Age"); // oops, a string! (macro?)age = value;

}

“The big problem”GC non-GC translationStore everything as shared_ptr

Replace every `new` with make_shared

Detecting use-cases for make_unique very difficultCircular references (weak_ptr<>?)

References require #includesNeed a list of typeheader for STL etc.

Circular references may need forward declarationsHeader groupings (at namespace or folder level)

Very tricky internal consistency (topological sort)Also a good idea for IDEs

Type translation is (relatively) easyint int32_tList<T> vector<T>

Function call translation is harderList.Add() vector.emplace_back(), but…Value vs ref. stuff

We need two convertersOne for .H filesAnother for .CPP files (implementation)

The option of doing everything inline isn’t considered

There are situations where 100% inlining doesn’t work

Naming conventionClean Unicode handlingAutomated API mapping

[email protected]@dnesterukCome to the JB booth! (R#C++, CLion)