2. Managed language = C#, Java, D etc.
GC (garbage collector), Unicode, …
Unmanaged language
Something that compiles to native code
More control, less safety
C/C++, VHDL, etc.
3. Performance
Stop-the-world GC
Low-level control (e.g., SIMD)
Collections (containers), multithreading
Defense against reverse-engineering
C#, Java are easy to decompile
Hardware support
CUDA, Xeon Phi
Portability (surprise!)
Sudden desire to write everything in С++
4. Lex the source code
Build AST
Resolve symbols
Traverse the tree, translating it to a different
language
Perfect translation is (of course) impossible
5. Translate syntax with fidelity
Fill the gaps in what’s missing
Replace equivalent constructs
List<> vector<>
Handle cases where 1-to-1
mapping is impossible
6. Integral types
Use types from <cstdint>
int int32_t, byte uint8_t, etc.
float/double as-is
Extended precision types (System.Decimal)
Need external libs
Slightly different init rules
7. Unicode
Most LoB apps do not absolutely require Unicode (nice to
have)
Relatively safe option:
string std::wstring
char wchar_t
Slightly more careless option: string/char
A completely safe solution has to allow strings to be nullptr
I.e., you either use char* or option<string>
Expensive, tedious, just use myString.empty()
Unicode in source (identifiers, literals, …) won’t work
9. Managed languages
Give types default values
Allow initialization right in the declaration
In both cases, initialization happens in the
(generated) ctor
In C++, types don’t have default values. So we
are forced to make a constructor ourselves
10. Property = field+getter+setter
Can be read or write-only
Can be automatic
Name of field not specified
explicitly
Offers no benefit over a field in C++
Can have an inline initializer
More ctor abuse
Two options here
GetXxx/SetXxx (safe, tedious)
__declspec(property)
(not C++ standard, but nicer)
int age;
public int Age
{
get { return age; }
set { age = value; }
}
// automatic
public int Age
{ get; set; }
11. __declspec(property(get = GetAge, put = PutAge))
int Age;
int GetAge() const { return age; }
void PutAge(int value) { … }
// later
Person p;
p.Age = 123; // calls PutAge()
12. Used in many places, e.g.:
Handling UI interactions
Property change notifications
C++ doesn’t have them
Boost.Signals
Tricky since event subscription is done with +=
And unsubscription with −=
14. 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;
}
15. “The big problem”
GC non-GC translation
Store everything as shared_ptr
Replace every `new` with make_shared
Detecting use-cases for make_unique very
difficult
Circular references (weak_ptr<>?)
16. References require#includes
Need a list of typeheader for STL etc.
Circular references may need forward
declarations
Header groupings (at namespace or folder
level)
Very tricky internal consistency (topological sort)
Also a good idea for IDEs
17. Type translation is (relatively) easy
int int32_t
List<T> vector<T>
Function call translation is harder
List.Add() vector.emplace_back(), but…
Value vs ref. stuff
18. We need two converters
One for .H files
Another for .CPP files (implementation)
The option of doing everything inline isn’t
considered
There are situations where 100% inlining doesn’t
work