JavaとC++の比較
C++はCとの互換性を保つため組込型の暗黙な型変換をある程度許可しているが、大抵のコンパイラでは警告を出す。また、複合型の暗黙型変換も定義できる。一方、Javaでは暗黙な変換としてネイティブ型の精度が大きくなる型変換(拡張変換)のみを許可する。他の変換は文法的に明示的なキャストを要求する。 この影響はJavaとC++双方にある条件式(if、whileとforの脱出条件)にも現れる。条件式の型はbooleanであることが期待されるが、intからbooleanへの精度が狭められる暗黙的型変換(縮小変換)が無いため、if (a = 5)のようなコードは、Javaではコンパイルエラーになる。これは、if (a == 5)のミスタイプに対する対策となるが、if (x)のようなコードをC++からJavaへ移植する際には型変換を明示することになる分、冗長になってしまう。
関数の引数を渡すとき、C++は参照渡しと値渡し両方をサポートする。Javaではすべての引数は値渡しであるが、オブジェクト(非プリミティブ変数)の引数は参照になり、これは間接参照が言語に備わっていることを意味する。
Javaのプリミティブ型は大きさと値の範囲が指定されている。一方、C++の組み込み型は最小限度が定められているものの、正確な大きさは定められておらず、環境によって異なる。また同じコンパイラでもバージョンが違えば型の大きさが異なることもあるし、コンパイラの設定で変更可能な場合もある。
C++で値の範囲が指定されていないとは、仮に同じ16ビット整数だとしても、ある環境では2の補数で[-32768, 32767]、別の環境では1の補数で[-32767, 32767]の範囲になるという例があるということである。C++11ではサイズと内部表現が規定された整数型(std::int32_tなど)がオプションとして追加された。 Javaの文字型charは、内部表現がUTF-16であることが規定されている。文字列を表現するクラスとして、java.lang.Stringが用意されている。一方、C++の文字型にはcharとwchar_t(ワイド文字)の2種類が存在し、それぞれの文字列クラスとしてstd::stringおよびstd::wstringが定義されているが、文字型の幅(ビット数)や内部表現はプラットフォームに依存する。規定されているのはcharのサイズが1バイト (sizeof(char) == 1) ということのみである。さらに、1バイトのビット数が規定されておらず、8ビット以上であればよい、という制約しかない。例えば、charがシングルバイト文字であったとしても、ASCIIであるとはかぎらないし、マルチバイト文字であったとしても、日本語環境でShift_JISあるいはEUC-JPが使われたり、中国語環境でGB 2312あるいはBig5が使われたり、もしくはUTF-8であったりしてもかまわない。また、wchar_tの内部表現は、UTF-16もしくはUTF-32であってもかまわないし、あるいはUnicodeと無関係の内部表現であってもかまわない。
JavaとC++の比較(ジャバとシープラスプラスのひかく)の記事では、JavaとC++の比較について説明する。
JavaとC++では多くのソースファイルでコードを分割するために異なる方法を使用する。Javaはすべてのプログラム定義でファイル名とパスが影響するパッケージシステムを使用する。Javaでは、コンパイラは実行可能クラスファイルをインポートする。C++はソースファイル間で宣言を分割するヘッダファイルのソースコード包含システムおよび名前空間を使用する。(参考: importとincludeの比較)
コンパイルされたJavaバイトコードファイルは通常、C++コンパイラの出力する機械語のコードファイルよりも小さい。第一に、Javaバイトコードは通常、ネイティブな機械語よりもコンパクトである。第二に、C++のテンプレートやマクロが類似コードの重複を発生させやすいことが挙げられる。第三に、Javaは常に標準ライブラリを動的リンクするため、標準ライブラリのコードを出力に含まないということが挙げられる。反面、Javaバイトコードを翻訳実行する環境(JVMやJIT)が要求される。
C++コンパイラは、Javaにはない、言葉通りのプリプロセッシング(前処理)の段階があることが特徴的である。これを用いるために、Javaユーザーの中には、ビルドプロセスにプリプロセッサを付加する者がいる。
双方の言語は、配列が固定サイズである。
Javaでは、配列は第一級オブジェクトであるが、C++では配列はベースとなるオブジェクトの連続した領域であり、最初の要素と随意的な配列の長さをポインタを使って参照しているに過ぎない。Javaでは、配列は境界チェックされ、長さもわかっているが、C++では配列を連続した領域として扱うだけである。C++とJava双方は、リサイズ、サイズ保存できるコンテナクラス (それぞれ、std::vector と java.util.Vectorまたはjava.util.ArrayList) を提供している。
Javaの除算と剰余演算子は0を切り捨てるよう正しく定義されている。C++は、これらの演算子が0を切り捨てるか「マイナス無限大に切り捨てる」かを明確に指定しない。Javaでは、-3 / 2は常に-1となる。一方、C++ではプラットフォームに依存し、-1を返すかも知れないし-2を返すかも知れない。C99およびC++11はJavaと同じように除算の仕様を定義しており、すべてのaとb (b != 0) で(a/b)*b + (a%b) == aを保証する。古いC/C++規格にこの保証がない理由は、仮にCPUの除算命令がこのような定義でなかったとしても、C/C++の除算を直接CPUの除算命令にコンパイルできるようにするためである。ただし、古いC/C++でも標準ライブラリのdiv()関数 (<stdlib.h>/<cstdlib>) を用いれば常に-3 / 2の商として-1という結果を得られる。