Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions book/hello.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,8 @@ Every C++ executable (as opposed to library) must have a `main()` function that
returns `int`. Returning `0` signifies that the program terminates without errors.
The final `return 0;` statement can be omitted in the `main()` function.

`#include` is a preprocessor. We'll meet more preprocessors in the future, for now
just accept that they are "naive macros" that are "expanded" before the actual
compilation.
Here `#include` copies the content of file called `iostream`, which has tens of
thousands lines, and pastes it here. Yes, it literally does so, and you can check
this by running `g++ -E main.c`, which "expands" all preprocessor statements.
`#include` is a preprocessor directive. We'll learn more about the preprocessor in later chapters, for now just accept that preprocessor directives are "naive macros" that are "expanded" before the actual compilation.
Here `#include` copies the content of file called `iostream`, which has tens of thousands lines, and pastes it here. Yes, it literally does so, and you can check this by running `g++ -E main.c`, which "expands" all preprocessor statements.

`iostream` contains definitions of functions and objects such as `std::cout` and
`std::endl`, which are used for IO manipulations. `cout` stands for "character
Expand Down Expand Up @@ -131,7 +127,7 @@ int a{5};
knitr::include_graphics("img/equal.png")
```

If you try `int a{5.5};` with this syntax, the compiler will give an error and abort (Figure \@ref(fig:braces) ). In addition, you can't separate the two parts:
If you try `int a{5.5};` with this syntax, the compiler will give an error and abort (Figure \@ref(fig:braces) ). In addition, you can't separate the two parts, thus enforcing that variables are not left uninitialized:

```c++
// not allowed
Expand All @@ -145,6 +141,30 @@ knitr::include_graphics("img/brace.png")

Of course, the uniform initialization syntax isn't invented just to prevent implicit conversion. As you'll see later, it can become handy when initializing complicated, non-primitive data types.

###`auto` vs `let`

Another key difference with declaring / initializing variables is in how types are inferred. In C++, the type of a variable can be inferred by replacing the type name with `auto`:

```c++
//These lines are equivalent
auto a = 5;
int a = 5;
```

Unlike Rust's `let` keyword, a variable declared with `auto` MUST be initialized in the same statement - that is, you cannot declare the variable with `auto`, then have the compiler infer the type from an initialization in another statement. Example:

```rust
// Rust - valid, type of a will be inferred as f32
let a;
a = 10. as f64;
```

```c++
// C++ - invalid, variable must be initialized and declared in the same statement
auto a;
a = 10.;
```

### Mutability

Variables are mutable by default. If you want to create an immutable variable, use the `const` keyword.
Expand Down Expand Up @@ -752,4 +772,4 @@ int& rj = j;
ri = rj;
// What are the values of i, j, ri and rj now?
// Hint: a reference cannot be re-assigned. What's the last line doing?
```
```