Compare C++, Go, Java, JavaScript, PHP, Python

2019-12-19


Comparing these languages is a rare thing, because these languages are very different and serve different purposes. But when I needed to learn them, while already knowing C++, I really needed a simple comparison table for an easier start. I did not find such comparison, so I created it. I hope this comparison table is useful for developers, which already have experience in some of the following languages, and are learning one of these languages.

You can find more details and examples in the following articles:



FeatureC++GoJavaJavascriptPHPPython
Created 1985 Bjarne Stroustrup
1972 Dennis Ritchie (C)
2009 Google 1995 Sun (Oracle) 1995 Netscape 1995  Rasmus Lerdorf 1991 Guido van Rossum
Purpose compiled object-oriented, generic, functional, low-level memory manipulation like C but with memory safety, garbage collection, structural typing and CSP-style concurrency high-level object-oriented implementation-independent high-level just-in-time compiled multi-paradigm, prototype-based object-orientation general-purpose web-development interpreted high-level general-purpose
Types
Type statically typed statically typed statically typed weakly dynamically typed (variables can be implicitly coerced to unrelated types) weakly dynamically typed with static typed features (strict_types) strongly dynamically typed (variables cannot be implicitly coerced to unrelated types)
Primitive numeric data types int and uint up to 64 bit. float up to 64 bit. int and uint up to 64 bit. float up to 64 bit. int up to 64 bit. float up to 64 bit. int stored as 64 bit float (up to 53 bit without precision loss). int and float is 64bit on x64 hardware. int converted to float if result is big int with unlimited precision. float up to 64 bit.
Boolean literals true
false
true 
false 
true 
false 
true
false
true 
false 
(case insensitive)
True
False
Type coercion Numeric no Numeric widening (byte ➞ short ➞ int ➞ long ➞ float ➞ double) Numeric, strings, objects etc. (disabled with ===) Numeric, strings etc. (disabled with ===) Numeric, container to bool
Immutability All objects are mutable if const is not used. Const object is immutable if it has no mutable members and const_cast is not used. Immutable: string Immutable: all wrappers (Boolean, Short, Integer, Long, Float, Double, Byte, Char, String) Immutable: string, number, boolean. Mutable: objects and arrays. Immutable: number, boolean, final class. Immutable: int, float, complex, string, tuple, frozen set, bytes. Mutable: list, dict, set, byte array.
Const meaning immutable pointer and/or value immutable binbind final (immutable binding) immutable binding const / define (immutable binding) -
Default slicing behavior vector copy constructor,
span is view of vector
[:] creates slice pointing to same array copyOfRange  slice copies immutable elements and object references array_slice and = copies elements or references [:] copies immutable elements and object references

islice creates view
Union union - - - - - (use struct to interpret bits differently)
Numerical type size guarantee no (depends on platform)
but has fixed width types
no (depends on platform)
but has fixed width types
yes no (not sure what will happen to float64 on 32 bit OS) no (depends on platform) yes (switches to bignum automatically)
Pointers and address operator yes (with arithmetic) yes (no arithmetic unless unsafe) no no no no
Statements and expressions
Logical operators !
&& (short-circuit)
|| (short-circuit)
!
&& (short-circuit)
|| (short-circuit)
! 
& 
| 
&& (short-circuit)
|| (short-circuit)
!
&& (short-circuit)
|| (short-circuit)
! 
&& (short-circuit)
|| (short-circuit)
not
and (short-circuit)
or (short-circuit)
Ternary operator test ? a : b  - test ? a : b  test ? a : b  test ? a : b  a if test else b
Goto goto  goto  - - goto  -
Strings
String concatenation operator + + + + . (dot) +
Internal string encoding No (bytes) No (bytes) UTF-16 UTF-16 No (bytes) Most compact of Latin-1, UCS-2 or UCS-4
Source file encoding any UTF-8 UTF-8, UTF-16, or UCS-2 any any any
Convert non-int string to int stoi("a") -> exception Integer.parseInt("a") -> exception parseInt("a") returns NaN int("a") -> exception
Detect formatting wrong type / number of args Manual with __attribute__((format))  Automatic Automatic not needed not needed not needed
Mutable string std::string, char* strings.Builder or bytes.Buffer StringBuffer (synchronized), StringBuilder Not needed (strings concatenation is optimized) Strings are mutable Not needed (strings concatenation is optimized)
For older Python 2 use ''.join()
Symbol ' character character character string or character unparsed multiline string string or character
Symbol " string string string string or character parsed multiline string string or character
Symbol ` - raw string multiline string multiline template literal execute deprecated alias for repr() 
Multiline string - - - `...` (template) '...' or nowdoc
"..." or heredoc
"""...""" or '''...''' 
Raw string literal - - - - - r'...' or r"..." 
Raw multiline string literal R"(...)"  `...` (CR is removed) `...`  String.raw`...` (template) - r"""...""" or r'''...''' 
Variable declarations
Local variable declaration int x = 1 var x = 1 
x := 1 
int x = 1  let x = 1 $x = 1  x = 1
Variable declarations are hoisted no no no hoisted no declarations no declarations
Functions
First class function support full yes, except named nested functions yes, except named nested functions and partial application full yes, except named nested functions and partial application yes, but nested anonymous functions are expressions only
Closure (stateful function) return lambda to std::function,
operator() 
return anonymous function return nested function inner anonymous class
return lambda expression
return nested function
Default argument passing By value
By value By value (primitive)
Reference by value (object)
By value (primitive)
Reference by value (object)
By value (primitive)
Reference by value (object)
Can change passed reference yes, if passed reference to pointer (&*) or pointer to pointer (**) - - - -
Variable number of arguments ...  Varargs
... 
*args, **kwargs
Function overloading yes (not by return type) - yes (not by return type) - -
Implicit functions inlining yes yes yes - no (PyPy does)
Explicit functions inlining inline  - - - (in JS inline function is named anonymous function) -
Function declarations are hoisted no no no hoisted hoisted no
Function (not lambda) declaration statement statement statement expression (returns value) statement statement
Lambda functions Yes Anonymous function Lambda expression Function assignment. Arrow functions. Anonymous function Cannot contain statements, only expressions. Do not create their own scope. Cannot raise or catch exceptions, have if blocks or loops. Cannot have multiple return points
Named arguments of function No No No Using destructuring:
function f({x, y} = {x:1, y:2}) {}
Yes (starting from PHP 8) Yes
Missing/extra parameters in a function call Will not compile Missing parameters get value of 'undefined'. Extra parameters get into 'arguments' object. Exception
Generator functions (yield output) no yes yes
Coroutines (yield output and input) C++20 or libraries yes (goroutine) no (so far) yes yes
Nothing
Check if variable was declared
Set variable to nothing Only with std::optional nil  null
Check for null: === null
Check for null or undefined: == null
null  None
Check for None: is None
Undefined (uninitialized) variables Variable can be undefined if not initialized, but it will return random value if used, instead of 'undefined'. Unitialized variables are zero Unitialized fields are zero/null
Compile error if reading uninitialized local variable
undefined
Check for undefined: typeof x === 'undefined'
Check for null or undefined: == null
null if used before initialization All variables are initialized - so there are no undefined variables.
Assignment expression (returns value) expression (returns value) statement (does not return value)
Scope
File scope Files do not have their own scope, but you can use static and unnamed namespace to create one:
namespace { a = 1; }
Files do not have their own scope, but you can create separate scope with anonymous function:
(function(){ let a=1; })();
or
!function(){ let a=1; }();
Files have their own scope
Namespace creation namespace, class, function, block class, function, block function namespace (contains classes, functions, consts), class, function function, class, module
Global functions and variables yes yes no (only in classes) yes yes
Access global variable direct direct no global scope direct GLOBAL $x;  direct
Declare variable in global scope from local scope impossible impossible no global scope x = 1 $GLOBALS['x'] = 1;  global x
x = 1
Object-oriented programming
Object oriented programming class-based methods, interface, embedding class-based prototype-based class-based
Private members yes yes - (only private variables and functions inside constructor) -
Can call constructor or method without instantiating an object no C.f(o) (have to pass some object instead of self)
Accessing object members member (or this->member if ambiguous) receiver in method declaration member (or this.member if ambiguous) this.member self.member
Can attach function to an object method no no classes o.func = function() {}; obj.f = f.__get__(obj)
Multiple inheritance yes no inheritance (but multiple embedding) single (can inherit multiple interfaces) single yes
Overload operators yes no classes no
Concurrency
Concurrency Concurrent - can use all processor cores Concurrent - can use all processor cores Concurrent - can use all processor cores Concurrent (web workers and worker threads) - can use all processor cores pthreads (threads), popen (processes) Limited (threading module is not concurrent if you cannot release GIL with i/o operation or external code, multiprocessing module uses processes instead of threads, Twisted uses event model)
Thread-local storage thread_local  - (can use gls package) ThreadLocal yes (in web worker) threading.local 
Detect races -fsanitize=thread  go -race  FindBugs, ConTest NodeRacer manual ?
Data structures
Hash tables std::unordered_map Object and Map dict, defaultdict
Array of different-typed elements std::vector<std::variant<int, double, ...>> array list
Immutable structure const e.g. unmodifiableList freeze any object tuple,frozenset,frozendict
Fixed size modifiable array C array[], std::array array[] array[] seal -
O(1) growing array vector slice[] ArrayList or Vector (thread-safe) Array list
Forward linked list forward_list - - - -
Doubly linked list list list  LinkedList - -
Hash set unordered_set map[type]bool, golang-set, intsets  HashSet can use Object set
Hash set with insertion order - - LinkedHashSet Set can use OrderedDict
Hash map unordered_map map  HashMap Object dict
Hash map with insertion order - orderedmap  LinkedHashMap Map OrderedDict
Sorted set set (balanced BST) gods.treeset  TreeSet (balanced BST) SortedSet (3rd party: balanced BST) SortedSet (3rd party: set + list of sorted lists of keys)
Sorted muiltiset multiset (balanced BST) - TreeMultiset (Google) - -
Sorted map map (balanced BST) gods.treemap  TreeMap (balanced BST) SortedMap (3rd party: balanced BST) SortedDict (3rd party: dict + list of sorted lists)
Sorted multimap multimap (balanced BST) go-multimap  MultiMap Object with arrays as values defaultdict(list), multidict (3rd party)
Double-ended queue with O(1) indexing deque deque ArrayDeque, LinkedList Deque (3rd party) deque
Stack adaptor for dequeue, vector or list slice[] Stack (subclass of Vector) Array use list, LifoQueue or deque
Queue adaptor for deque or list listdeque Deque Array (slow shift) deque, Queue (thread-safe)
Priority queue priority_queue (based on vector or deque) heap (binary heap) PriorityQueue (3rd party) heapq
Array with elements of different type std::vector<std::any>,
std::vector<std::variant> 
[]interface{} Object[] arr  Array  list 
Error handling
Exceptions trythrowcatch panicdeferrecover trythrowcatchfinally trythrowcatchfinally tryraiseexceptelsefinally
Print stacks on failure install SIGSEGV handler,
insert backtrace into exception
automatic,
debug.PrintStack() 
Thread
.currentThread() .getStackTrace()
 
console.trace(),
new Error(); .stack
automatic,
get from exception
Memory management
Garbage collection no yes yes yes yes
Stack/heap allocation Explicit (new). Objects can be in heap or stack. Implicit (escape analysis) Explicit (new).
Objects always in heap.
Implicit Implicit Implicit
Default stack size static 8MB dynamic 8KB-1GB static 512KB static static static
Environment
Entry point int main (int argc, char *argv[])  func main()  public static void main(String args[])  first line first line if __name__ == "__main__": 
Function before entry point __attribute__ ((__constructor__)) void init(void)  func init()  static {}  - - -
Command-line arguments main() arguments from 1 os.Args[1:]  main() arguments from 0 process.argv from 1 $argv from 1 sys.argv[1:] 
Code management and integration
Linking header=file (include) or module=file (import) package=files (import) in module package=files (import) in module, service, image, layer module=file (import) in package=folder module=file (import) in package=folder
Define macro #define no no
Preprocessor and macros yes - (but can substitute symbols at build time with -X flag) - - -
Eval - - - (can use ScriptEngine to evaluate JS) eval eval 
Low level programming Inline assembly Link SWIG, C, Asm Link C, Asm with JNI WebAssembly PHP extension Cython, SWIG, ctypes
Performance
Execution time 2 4 4 4 100
Compilation time slowest to machine code fastest to machine code fast to byte code no (interpreted) no (interpreted)
Can skip out-of range checks yes (indexing [] by default skips, at() checks) - - - -
Tools
Testing many frameworks testing  JUnit, TestNG  pytest, unittest 
Debug gdb Delve jdb Chrome phpdbg pdb
Character char (1 byte) rune (4 bytes) char (2 bytes) no (string only) no (string only) no (string only)
Digit separator in literal 100'000
(since C++14)
100_000
(since 1.13)
100_000
(since SE 7)
100_000
(since ES2021)
100_000
(since 7.4)
100_000
(since 3.6)
Static variable in function yes no (use global or closure) no (use static class variable or instance variable) no (use closure or function property) yes no (use global or function attribute or closure)
Variable with same name in nested block hides external hides external compilation error hides external rewrites external variable value (if same function scope or imported with GLOBAL) 1. hides external without nonlocal
2. rewrites external variable value (if same function scope or imported with nonlocal)
Case sensitive names
Integer division integer / integer integer / integer integer / integer Math.floor(x / y)  floor($x / $y) x // y (python 3)
x / y (python 2)
Integer expressions promotion byte, short, char to int 
Type inference auto a = b;  a := b  var a = b;  always always always
Prefix increment ++x expression - expression expression expression -
Postfix increment x++ expression statement expression expression expression -
Assignment is expression yes no yes yes yes := only
Labeled break and continue break label; 
continue label;
New object
Copy object
Reference to object
Default member access struct: public
class: private
accessible by the classes of the same package
Static member access Class::Member Class.Member
Nested class can access private members yes
Anonymous class yes yes
Class nested in function yes yes
Default parameter values yes no no
Division by zero exception no yes
Exiting main thread finishes all yes yes no
Generics templates generics
Lambda syntax x -> x
(x, y) -> { return x; }
Can modify captured local variable no (only instance variable through capturing this)
Members visibility
Base class constructor called automatically yes no
Object identity and reference identity