From 7768af990923bda242664b921a34bb2ec69f2f1f Mon Sep 17 00:00:00 2001 From: eliasreid <47339667+eliasreid@users.noreply.github.com> Date: Sat, 14 Nov 2020 17:48:21 -0500 Subject: [PATCH 1/2] wording change around pre-processor intro Slight change to describe #include as a "preprocessor directive" rather than a "preprocessor" --- book/hello.Rmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/hello.Rmd b/book/hello.Rmd index 2941268..05f6546 100644 --- a/book/hello.Rmd +++ b/book/hello.Rmd @@ -19,7 +19,7 @@ A couple of things to note here: 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. +`#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 output", and `endl` stands for "endline" (it appends `\n` and flushes the buffer). `<<` is the bitwise left shift operator, and the designers of C++ decided that overloading bitwise shift operators for `cout` and `cin` can make C++ look fancy from the beginning. That's why we need to learn yet another special syntax. @@ -662,4 +662,4 @@ int& ri = i; int& rj = j; ri = rj; // what are the values of i, j, ri and rj now? -``` \ No newline at end of file +``` From 30ae64626b2a670a4b627eddf8abb9af3c923dba Mon Sep 17 00:00:00 2001 From: eliasreid <47339667+eliasreid@users.noreply.github.com> Date: Sat, 14 Nov 2020 18:18:52 -0500 Subject: [PATCH 2/2] initialization wording changed, add section on auto vs let --- book/hello.Rmd | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/book/hello.Rmd b/book/hello.Rmd index 05f6546..9c6072b 100644 --- a/book/hello.Rmd +++ b/book/hello.Rmd @@ -74,7 +74,7 @@ For floating numbers, `f32` and `f64` correspond to `float` and `double`, respec ## Variables -Like in Rust, creating a variable requires two steps, declaration and initialization. In C++, there are usually more than one syntax to do any task, and these two basic operations are no exception. +Like in Rust, creating a variable requires two steps, declaration and initialization. In C++, there are many different ways to perform these steps. The traditional syntax for declaration and initialization is ` = ;`, and these two steps can be separated: @@ -91,7 +91,9 @@ int a = 5.5; assert(a == 5); ``` -The value will be implicitly converted. Instead of giving a warning or simply disallowing this (recent compilers DO give a warning; see Figure \@ref(fig:equal)), the designers of C++ decided to invent another syntax for declaration and initialization, using curly braces: +The value will be implicitly truncated to an integer, effectively erasing the decimal component (although recent compilers do provide a warning; see Figure \@ref(fig:equal)). + +An often preferred method of initialization is to use curly braces, as seen in the example below: ```c++ int a{5}; @@ -101,7 +103,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 @@ -113,6 +115,30 @@ a{5} knitr::include_graphics("img/equal.png") ``` +###`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.