Hello, world! - Cpp2 and cppfront — An experimental 'C++ syntax 2' and its first compiler (original) (raw)

graph LR
  A["` hello.cpp**2** `"] ==> B(["` **cppfront** `"]);
  B ==> C[hello.cpp];
  C ==> D([Your favorite<br> C++ compiler<p>... and IDE / libraries / build<br>system / in-house tools / ...]);

A hello.cpp2 program

Here is the usual one-line starter program that prints Hello, world!. Note that this is a complete program, no #include required:

hello.cpp2 — on one line

[](#%5F%5Fcodelineno-0-1)main: () = std::cout << "Hello, world!\n";

But let's add a little more, just to show a few things:

hello.cpp2 — slightly more interesting

[](#%5F%5Fcodelineno-1-1)main: () = { [](#%5F%5Fcodelineno-1-2) words: std::vector = ( "Alice", "Bob" ); [](#%5F%5Fcodelineno-1-3) hello( words[0] ); [](#%5F%5Fcodelineno-1-4) hello( words[1] ); [](#%5F%5Fcodelineno-1-5)} [](#%5F%5Fcodelineno-1-6) [](#%5F%5Fcodelineno-1-7)hello: (msg: std::string_view) = { [](#%5F%5Fcodelineno-1-8) std::cout << "Hello, (msg)$!\n"; [](#%5F%5Fcodelineno-1-9)}

This short program code already illustrates a few Cpp2 essentials.

Consistent context-free syntax. Cpp2 is designed so that there is one general way to spell a given thing, that works consistently everywhere. All Cpp2 types/functions/objects/namespaces are written using the unambiguous and context-free declaration syntax "name : kind = statement". The : is pronounced "is a," and the = is pronounced "defined as."

All grammar is context-free. In particular, we (the human reading the code, and the compiler) never need to do name lookup to figure out how to parse something — there is never a "vexing parse" in Cpp2. For details, see Design note: Unambiguous parsing.

Simple, safe, and efficient by default. Cpp2 has contracts (tracking draft C++26 contracts), inspect pattern matching, string interpolation, automatic move from last use, and more.

Simplicity through generality + defaults. A major way that Cpp2 delivers simplicity is by providing just one powerful general syntax for a given thing (e.g., one function definition syntax), but designing it so you can omit the parts you're not currently using (e.g., where you're happy with the defaults). We're already using some of those defaults above:

For details, see Design note: Defaults are one way to say the same thing.

Order-independent by default. Did you notice that main called hello, which was defined later? Cpp2 code is order-independent by default — there are no forward declarations.

Seamless compatibility and interop. We can just use std::cout and std::operator<< and std::string_view directly as usual. Cpp2 code works with any C++ code or library, including the standard library, using ordinary direct calls without any wrapping/marshaling/thunking.

C++ standard library is always available. We didn't need #include <iostream> or import std;. The full C++ standard library is always available by default if your source file contains only syntax-2 code and you compile using cppfront's -p (short for -pure-cpp2), or if you use -im (short for -import-std). Cppfront is regularly updated to be compatible with C++23 and the latest draft C++26 library additions as soon as the ISO C++ committee votes them into the C++26 working draft, so as soon as you have a C++ implementation that has a new standard (or bleeding-edge draft standard!) C++ library feature, you'll be able to fully use it in Cpp2 code.

Building hello.cpp2

Now use cppfront to compile hello.cpp2 to a standard C++ file hello.cpp:

Call cppfront to produce hello.cpp

[](#%5F%5Fcodelineno-2-1)cppfront hello.cpp2 -p

The result is an ordinary C++ file that looks like this: 1

hello.cpp — created by cppfront
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #define CPP2_IMPORT_STD Yes #include "cpp2util.h" auto main() -> int; auto hello(cpp2::instd::string\_view\ msg) -> void; auto main() -> int{ std::vector words {"Alice", "Bob"}; hello(CPP2_ASSERT_IN_BOUNDS_LITERAL(words, 0)); hello(CPP2_ASSERT_IN_BOUNDS_LITERAL(std::move(words), 1)); } auto hello(cpp2::instd::string\_view\ msg) -> void { std::cout << ("Hello, " + cpp2::to_string(msg) + "!\n"); }

Here we can see more of how Cpp2 makes its features work.

How: Consistent context-free syntax.

How: Simple, safe, and efficient by default.

How: Simplicity through generality + defaults.

How: Order-independent by default.

How: Seamless compatibility and interop.

How: C++ standard library always available.

Building and running hello.cpp with any recent C++ compiler

Finally, just build hello.cpp using your favorite C++20 compiler, where CPPFRONT_INCLUDE is the path to /cppfront/include:

MSVC (Visual Studio 2019 version 16.11 or higher)

[](#%5F%5Fcodelineno-4-1)> cl hello.cpp -std:c++20 -EHsc -I CPPFRONT_INCLUDE [](#%5F%5Fcodelineno-4-2)> hello.exe [](#%5F%5Fcodelineno-4-3)Hello, world!

GCC (GCC 10 or higher)

[](#%5F%5Fcodelineno-5-1)$ g++ hello.cpp -std=c++20 -ICPPFRONT_INCLUDE -o hello [](#%5F%5Fcodelineno-5-2)$ ./hello.exe [](#%5F%5Fcodelineno-5-3)Hello, world!

Clang (Clang 12 or higher)

[](#%5F%5Fcodelineno-6-1)$ clang++ hello.cpp -std=c++20 -ICPPFRONT_INCLUDE -o hello [](#%5F%5Fcodelineno-6-2)$ ./hello.exe [](#%5F%5Fcodelineno-6-3)Hello, world!

➤ Next: Adding cppfront to your existing C++ project