Mind Boggling Questions in C++

This is an update of a post that originally appeared on December 13, 2011.

I constantly tell readers they need to view my books as a starting point, rather than the end of their education on a particular subject. This sentiment holds true for C++ All-In-One for Dummies, 4th Edition as it does for all of my books. When you read this book, you get a really good start with C++. By the time you’re finished, you can create some useful applications and you know enough about the Code::Blocks IDE to use it effectively. Fortunately, there are many places online to expand when it comes to C++ and I ran across one of them in an article entitled, Amusing C++. The title, more than anything else, caught my attention. What, after all, could be amusing about C++?

This is one of those sorts of articles I wish I had thought to write myself. The author has a unique perspective about C++ and some of the issues you could face when working with it. More importantly, the article uncovers some interesting compatibility issues between compilers, all the while having fun with the C++ language.

These sorts of mind boggling questions force even professional developers to think about the language and how it works. It may seem as if a language specification is solid, but then you see that there are gaps in how the specification is put together and that there is room in the standards for unique vendor implementations. Working with unique implementations can lead to innovation, but it can also lead to all sorts of compatibility issues when you need to move your application from one product to another.

After you’ve completed reading my book, make sure you continue on with online resources. Of course, the place that you should look first for issues related to this book (and some general interest C++ topics) is the C++ All-in-One for Dummies, 4th Edition category on this blog. It’s a shame that this particular Dummies book doesn’t include the Parts of Tens feature that is found in other Dummies books. However, here are ten places you can look for C++ materials and examples:

Where do you get additional information about C++? What sorts of information do you look for on these sites? Let me know at [email protected].

Comment and Document Updates for CI/CD

In reading about Continuous Integration/Continuous Deployment (CI/CD) I often find ways to manage the code, to get people around the code, to keep errors out of the code, and so on. It’s all about the code. Developers have, in fact, developed myriad ways to keep code size small, updated, deployed, tested, and so on to ensure that users have what they want, when the they want it (if not before). Sometimes my head spins on its axis after reading such documents because it becomes a high speed dizzying affair. It’s somehow assumed that everyone can just keep up. Except, there are new people and older people and people with lesser attention spans who can’t keep up, which is why comments and documentation are so important.

As part of the coding process, developers also need to update both comments and documentation or someone will come along and make modifications based on outdated information. Even though making such updates seems like a waste of time since everyone should be able to keep up, the truth is that these updates ultimately save time. However, the updates, when they occur (which apparently isn’t often) are often made in a haphazard manner reminiscent of an old Keystone Cops movie.

Adding a process, a workflow, to the CI/CD mill is important to ensure that everything remains in sync: code, comments, and documentation. A best practice way to accomplish this task is to add steps to every update process so that nothing is left behind. Here’s how you could approach the problem:

  1. Perform the required code updates.
  2. During testing, ensure that the comments within the code actually match what the code is doing. Testing and other review processes should not only look at the code, but the comments too.
  3. Update the documentation as final testing occurs. Make sure to include these elements:
    • Text
    • Drawings
    • Mockups
    • Visual Aids
    • Videos
    • Any other documentation elements
  4. Specify that any old comments/documentation are outdated using one of these approaches:
    • Mark it as deprecated
    • Remove it from the work area and put it in an archive
    • Delete it completely
  5. Deploy the application update. If you don’t deploy the update after these steps are done, they won’t get done. Everyone will wander off somewhere and forget all about any sort of comment or documentation update.

Obviously, the approach you end up using has to meet the requirements of your organization. It also has to be simple enough that people will actually, albeit begrudgingly, perform the work. What methods do you use to keep everything in sync at your organization? Let me know at [email protected].

Choosing the GNU C++ Compiler

This is an update of a post that originally appeared on April 23, 2012.

A number of readers have written to ask me about the reason I chose the GNU C++ computer for C++ All-In-One for Dummies, 4th Edition. After all, there are many different C++ compilers on the market today. Here are the reasons I feel that the GNU C++ Compiler is the best choice today:

  • Standards Adherence: From what I’ve read and seen in my own coding efforts, the GNU C++ compiler adheres a bit better to the current standards. There are other compilers, such as Microsoft’s Visual C++, that include a host of special additions and exceptions that don’t adhere to the standard. Given the audience for this book, using a compiler that’s strong on the standards is a must. (This book doesn’t use any of the GNU C++ extensions.)
  • Cross-Platform Compatibility: This book has a mixed audience. I’ve received so many e-mails from Macintosh readers that I’ve provided a number of blog posts just for this group. Linux developers also like this compiler and have used my book to learn how to use it. Because there are so many different platforms that this compiler works on, I can reach a much broader audience with the book and help more people write applications in C++ as a result.
  • CodeBlocks Support: In order to write good C++ code, you really do need a good IDE. CodeBlocks is a free compiler that works well on Linux, Macintosh, and Windows machines. If I had chosen another compiler, it may not have been possible to provide great support for all three platforms and some readers would have been left out.
  • Community Support: Both the GNU C++ compiler and CodeBlocks enjoy a broad range of support from the open source community. Getting help with either product is relatively easy and normally free.
  • Cost: Many of the readers of this book are students of limited means or are hobbyists learning to write C++ applications on a shoestring. Using the GNU C++ compiler coupled with CodeBlocks offers a method of teaching C++ programming that doesn’t require any investment by the reader. If cost hadn’t been a factor, there are probably other compilers on the market that might be a little better choice than using GNU C++.
  • Mobile Device Support: Many of my readers now what to be able to code from anywhere at anytime using their mobile device. Quite a few of the online compilers rely on GNU C++. (You also find support for Android devices in the book now using CppDroid in Chapter 2.) In many respect, you could view this as a fourth supported platform for my book.

Yes, I could have used some other compiler when writing this book, but at the time, GNU C++ seemed to be the best choice available and I still think it’s the best choice today. Of course, it’s always nice to hear about alternatives. If you think there is a strong competitor for GNU C++ that’s free and runs on all three of the target platforms for this book, let me know at [email protected]. Make sure you provide me with complete information, including a URL for the compiler’s site.

Creating a CodeBlocks Project with Multiple Existing Files

This is an update of a post that originally appeared on July 26, 2011.

Most real world C++ projects include multiple source files. Book I Chapter 7 of C++ All-In-One for Dummies, 4th Edition shows how to create a project that has multiple source files starting on page 170. The first example (page 177), found in \CPP_AIO4\BookI\Chapter07\MultipleSourceFiles, discusses two .cpp files. The second example starts on page 179 and you find it in \CPP_AIO4\BookI\Chapter07\MultipleSourceFiles2. This example includes two .cpp files and a single .h file. I’ll use the files from the second example for this post. The example works the same as the one in the book, but in this case, we’ll start with the three files and create a project around them.

Defining the Project

You need to start with a Code::Blocks project. It’s possible to use either an existing project or create a new project to hold the files (I’m doing the latter and naming the new product MultipleSourceFiles3). In either case, once you have a project to use, you simply add the files you want to it, set the build options for those files, and then create your application. The following steps create a new project, add the files from MultipleSourceFiles2 to it, set the build options, compile the resulting project, and show you the results.

  1. Choose File > New > Project. You’ll see the New From Template dialog box.
  2. Highlight the Empty Project template as shown here:
  3. Click Go. You’ll see the Empty Project wizard. If you’re seeing the Welcome screen, click Next to get past it.
  4. Type the name of the project (the example uses MultipleSourceFiles3) in the Project Title field and choose a location for the project (the example uses \CPP_AIO4\BookI\Chapter07\) in the Location field. If you’re following the example, your wizard should look similar to the one shown here:The Empty Project configuration information for MultipleSourceFiles3.
  5. Click Next. Look in the Compiler field and ensure that the GNU GCC Compiler option is selected.
  6. Click Finish. The wizard creates a blank project for you.

Referencing the Other Project Source Files

At this point, you have an empty project without any files in it. However, you can add files to any existing project. The following steps add the files from the MultipleSourceFiles2 project to this project.

  1. Right click the project entry (MultipleSourceFiles3) in the Projects tab of the Management window and choose Add Files from the context menu. You see the Add Files to Project dialog box shown here: Adding new files to an empty project.
  2. Locate the \CPP_AIO4\BookI\Chapter07\MultipleSourceFiles2 folder on your system.
  3. Click on main.cpp. Ctrl+Click on safestuff.cpp and safestuff.h. You’ll see all three files added to the File Name field.
  4. Click Open. You’ll see the Multiple Selection dialog box. This dialog box contains entries for each of the builds that you specified when creating the project. The default is to use the files you’re adding in all of the builds as shown here. (The example uses all of the files in all of the builds.)Ensure the that targets will appear in all build types.
  5. Configure the files you’ve selected by choosing the build the file should appear part of and click OK. You’ll see all three files added below the MultipleSourceFiles3 entry in the Projects tab of the Management window as shown here:The files from MultipleSourceFiles2 are referenced in this project.

The referencing technique adds existing files to a different project. Notice that the files are still referenced in the original project. If you make a change to these files, the changes will also appear in the original project.

Copying the Other Project Source Files

Referencing files isn’t always what you want to do. So, you need an alternative for those situations where you want a copy of the file in a new project (allowing changes in the new project that won’t affect the existing project). In this case, follow these steps instead:

  1. Right click the project entry (MultipleSourceFiles3) in the Projects tab of the Management window and choose Add Files from the context menu. You see the Add Files to Project dialog box.
  2. Locate the \CPP_AIO4\BookI\Chapter07\MultipleSourceFiles2 folder on your system.
  3. Click on main.cpp. Ctrl+Click on safestuff.cpp and safestuff.h. You’ll see all three files added to the File Name field.
  4. Right click main.cpp and choose Copy from the context menu.
  5. Locate the \CPP_AIO4\BookI\Chapter07\MultipleSourceFiles3 folder on your system.
  6. Right click inside the file selection area and choose Paste from the context menu. You see the files pasted into the new location as shown here: Actually copying the files to a new location.
  7. Click Open. You’ll see the Multiple Selection dialog box.
  8. Configure the files you’ve selected by choosing the build the file should appear part of and click OK. You’ll see all three files added below the MultipleSourceFiles3 entry in the Projects tab of the Management window as shown here (notice that they’re now actually part of MultipleSourceFiles3 and not just a reference):The files are now copied, not referenced.

Many developers find the need to use existing files in a project. It’s something you’ll do quite often, especially with header files. Of course, when working with header files you also have the option of using the #include directive. Please let me know if you have any questions about this process at [email protected].

Choosing a First Language to Learn

My first programming experience (during the time of the dinosaurs) involved using a light panel to enter machine code into a rudimentary computer with 3 KB (yes, that’s KB) of RAM. The output was also in light form and I needed to decode the lights to determine if my code worked right. I worked with various systems in various ways over the next several years. By the time I got to college, the first language I learned there was BASIC (Beginner’s All-purpose Symbolic Instruction Code), then PC assembler, followed by Pascal. In fact, I’ve just stopped counting the number of languages I’ve learned over the years because each language has a place in my programmer’s toolbox. Of course, the question is what language you should learn first. I get asked that question quite often because there are a huge number of languages available today and no one wants to invest time in a language that’s going nowhere.

Part of the answer to the question of what to learn first is what you intend to do with the language. Each language has features that make it better at performing specific tasks. Programming languages can be split into those that are designed for a special purpose and those that are designed for a general purpose. A special purpose language, such as Structured Query Language (SQL), could be a good choice if you intend to move into database work immediately. However, for most people, a general purpose language works better because you can use it for a wider variety of tasks without bending yourself into a pretzel shape to do it.

A good place to start if you want to choose a language that’s popular enough to help you get a job afterward is the TIOBE index. It shows a listing of which languages are most popular today. As I’m writing this, Python is the most popular language on the list, but that could change tomorrow. Generally, any of the top ten languages on the list are good choices.

Of course, you want a programming language that is easy to learn. C/C++, C#, and Java are all complex languages with great flexibility. Furthermore, C/C++ and C# can help you work at a low level with the computer hardware. These languages have a steep learning curve and may not provide the best choices for a starting point. That said, if you have a line on a job that uses any of these languages, you could do worse than start here, just be prepared to burn the midnight oil learning.

The language I suggest people learn as a starting point is Python. In fact, Beginning Programming with Python For Dummies, 3rd Edition makes a point of showing you just how easy things can be. You don’t even need to invest in any special software, the book shows you how to use Google Colab so that you could conceivably learn how to program on your smartphone or TV. Others must agree with me because Python has turned into the language that the education industry turns to most often for budding programmers.

There are a lot of programming languages available today. You need to research the choice by taking into account what your personal needs are and what sort of job you want to get afterwards. You might find that something like JavaScript or Ruby will provide benefits that you can’t get with Python. Which language do you think will work best for you? Let me know your reasons at [email protected].

Creating Sensible Error Trapping

This is an update of a post that originally appeared on May 23, 2011.

Errors in software happen. A file is missing on the hard drive or the user presses an unexpected key combination. There are errors of all shapes and sizes; expected and unexpected. The sources of errors are almost limitless. Some developers look at this vastness, become overwhelmed, and handle all errors the same way—by generating an ambiguous exception for absolutely every error that doesn’t help anyone solve anything. This is the worst case scenario that’s all too common in software today. I’ve talked with any number of people who have had to employ extreme effort just to figure the source of the exception out; many people simply give up and hope that someone has already discovered the source of the error.

At one time, error handling functionality in application development languages was so poor that it was possible to give the developer the benefit of a doubt. However, with the development tools that developers have at their disposal today, there is never a reason to provide an ambiguous “one size fits all” exception. For one thing, developers should make a distinction between the expected and the unexpected. Any expected error—a missing file for example—should be handled directly and specifically. If the application absolutely must have the file and can’t recreate it, then it should display a message saying which file is missing, where it is missing from, and possibly how to obtain another copy.

Even more than simply shoving the burden onto the user, however, modern applications have significantly more resources available for handling the error automatically. For example, it’s quite possible to use an Internet connection to access the vendor’s Web site and automatically download a missing application file. Except to tell the user what’s happening when the repair will take a few minutes, the application shouldn’t even bother the user with this particular kind of error—the repair should be automatic.

All of my essential programming books include at least mentions of error handling, debugging, exceptions, and other tasks associated with running code efficiently and smoothly. For example, Part IV of C++ All-In-One for Dummies, 4th Edition is devoted to the topic of debugging. Part V Chapter 3 of this same book talks about exceptions. If you’re a C# developer, C# 10.0 All-in-One for Dummies discusses exception handling in Book I Chapter 9. Book IV Chapter 2 discusses how to use the debugger to find errors. The point is that it’s essential to handle errors in your applications in a manner that makes sense to the users who rely on the application daily and the developers who maintain it.

Note that many of my newer books provide instructions for working with online IDEs, most especially Google Colab. These online IDEs rarely provide built-in debugging functionality, so then you need to resort to other means, such as those expressed in Debugging in Google Colab notebook.

Exceptional conditions do occur. However, even in these situations the developer must avoid the generic exception at all costs. If an application experiences an unexpected error and there isn’t any way to recover from it automatically, the user requires as much information as possible about the error in order to fix it. This means that the application should diagnose the problem as much as possible. Don’t tell the user that the application simply has to end—there is never a good reason to include this sort of message. Instead, tell the user that the application can’t locate a required resource and specify the resource in as much detail as possible. If possible, let the user fix the resource access problem and then retry access before you simply let the application die an ignoble death. Remember this! Any exception that your application displays means that you’ve failed as a developer to locate and repair the errors, so exceptions should be reserved for truly exceptional conditions.

Not everyone agrees with my approach to error trapping, but I have yet to hear a convincing argument to provide unreliable, non-specific error trapping in an application. Poor error trapping always translates into increased user dissatisfaction, increased support costs, and a reduction in profitability. Let me know your thoughts on the issue of creating a sensible error trapping strategy at [email protected].

Accessing a Global String

This is an update of a post that originally appeared on June 30, 2011.

Some examples work well across multiple editions of my book with slight modifications, so if you have the third edition of my book and this code looks familiar, it probably is with small changes. The example in question in this case now appears in Book I Chapter 7 of C++ All-In-One for Dummies, 4th Edition. The example shown in Listings 7-6, 7-7, and 7-8 describes how to declare a global int variable using extern and one reader wanted to extend this example to the string type. The reader had tried several times, but kept getting the following error message (in fact, you can find this same error in Code::Blocks 8.02 and 10.05 and the update in this post works with both versions):

error: 'string' does not name a type

I’m assuming that you’ve already read the discussion about this example (be sure you read the entire section from pages 183 to 185). Creating a fix for this problem isn’t hard, but providing some example code will make things easier to understand. The first issue is to include the required support in main.cpp (shown in Listing 7-6). Here’s an updated version that includes an entry for a string variable named CheeseburgerType.

#include <iostream>
#include <string>
#include "sharealike.h"
 
using namespace std;
 
int main()
{
  DoubleCheeseburgers = 20;
  CheeseburgerType = "Deluxe";
  EatAtJoes();
  return 0;
}

As you can see, you must provide #include <string> and then set CheeseburgerType to a value, which is "Deluxe" in this case. Otherwise, the example works precisely the same as before.

Let’s look at sharealike.h next (Listing 7-7). The following code changes are essential or the example will never work.

#ifndef SHAREALIKE_H_INCLUDED
#define SHAREALIKE_H_INCLUDED
 
using namespace std;
 
extern int DoubleCheeseburgers;
extern string CheeseburgerType;
void EatAtJoes();
 
#endif // SHAREALIKE_H_INCLUDED

Notice the inclusion of using namespace std;. The example will fail to compile without this statement added unless you specify the namespace as part of the type declaration. Once you define this addition, you can create the extern string CheeseburgerType; declaration. Of course, if string were part of another namespace, you’d use that namespace instead.

The final part of the puzzle is to create the required implementation. This part appears in sharealike.cpp (Listing 7-8). Here’s the final piece of the example:

#include <iostream>
#include <string>
#include "sharealike.h"
 
using namespace std;
 
int DoubleCheeseburgers;
string CheeseburgerType;
 
void EatAtJoes() {
  cout << "How many cheeseburgers today?" << endl;
  cout << DoubleCheeseburgers << " " << CheeseburgerType << endl;
 }

As with main.cpp, you must add the appropriate #include. In addition, this part of the example updates EatAtJoes() to include CheeseburgerType in the output. When you run this example, you’ll now see a cheeseburger type in the output as shown here:

The output of the updated version of GlobalVariable shows the kind of cheeseburger.
The output of GlobalVariable now shows the kind of cheeseburger.

Are there any questions on this extension? Please let me know at [email protected]. You can download the updated version of the code as GlobalVariable2 here:

Checking Your Compiler in Code::Blocks

This is an update of a post that originally appeared on April 6, 2011.

Compilers are important because they turn your human-readable source code into executable code that the computer understands. Selecting the right compiler is essential if you want to obtain the best results from your application. Some readers have asked, “Just how do you select a compiler when working with C++ All-In-One for Dummies, 4th Edition?” The book assumes that you’re using the GNU GCC Compiler setting and there isn’t any guarantee another compiler will work with the book’s source code. Use these steps to check your compiler setting.

  1. Open the Code::Blocks application.
  2. Choose Settings | Compiler and you see the Global Compiler Settings dialog box shown here:
    A display of the Global Compiler Settings dialog box in Code::Blocks.
  3. Choose GNU GCC Compiler in the Selected Compiler field as shown in the figure.
  4. Click OK.

You should be ready to work with the book’s code at this point. Let me know if you have any problems choosing the right compiler at [email protected].

Creating Useful Comments

This is an update of a post that originally appeared on November 21, 2011.

A major problem with most applications today is that they lack useful comments. It’s impossible for anyone to truly understand how an application works unless the developer provides comments at the time the code is written. In fact, this issue extends to the developer. A month after someone writes an application, it’s possible to forget the important details about it. In fact, for some of us, the interval between writing and forgetting is even shorter. Despite my best efforts and those of many other authors, many online examples lack any comments whatsoever, making them nearly useless to anyone who lacks time to run the application through a debugger to discover how it works.

Good application code comments help developers of all stripes in a number of ways. As a minimum, the comments you provide as part of your application code provides these benefits.

  • Debugging: It’s easier to debug an application that has good comments because the comments help the person performing the debugging understand how the developer envisioned the application working.
  • Updating: Anyone who has tried to update an application that lacks comments knows the pain of trying to figure out the best way to do it. Often, an update introduces new bugs because the person performing the update doesn’t understand how to interact with the original code.
  • Documentation: Modern IDEs often provide a means of automatically generating application documentation based on the developer comments. Good comments significantly reduce the work required to create documentation and sometimes eliminate it altogether.
  • Technique Description: You get a brainstorm in the middle of the night and try it in your code the next day. It works! Comments help you preserve the brainstorm that you won’t get back later no matter how hard you try. The technique you use today could also solve problems in future applications, but the technique may become unavailable unless you document it.
  • Problem Resolution: Code often takes a circuitous route to accomplish a task because the direct path will result in failure. Unless you document your reasons for using a less direct route, an update could cause problems by removing the safeguards you’ve provided.
  • Performance Tuning: Good comments help anyone tuning the application understand where performance changes could end up causing the application to run more slowly or not at all. A lot of performance improvements end up hurting the user, the data, or the application because the person tuning the application didn’t have proper comments for making the adjustments.

The need for good comments means creating a comment that has the substance required for someone to understand and use it. Unfortunately, it’s sometimes hard to determine what a good comment contains in the moment because you already know what the code does and how it does it. Consequently, having a guide as to what to write is helpful. When writing a comment, ask yourself these questions:

  • Who is affected by the code?
  • What is the code supposed to do?
  • When is the code supposed to perform this task?
  • Where does the code obtain resources needed to perform the task?
  • Why did the developer use a particular technique to write the code?
  • How does the code accomplish the task without causing problems with other applications or system resources?

There are many other questions you could ask yourself, but these six questions are a good start. You won’t answer every question for every last piece of code in the application because sometimes a question isn’t pertinent. As you work through your code and gain experience, start writing down questions you find yourself asking. Good answers to aggravating questions produce superior comments. Whenever you pull your hair out trying to figure out someone’s code, especially your own, remember that a comment could have saved you time, frustration, and effort. What is your take on comments? Let me know at [email protected].

C++ Data Type Usage

This is an update of a post that originally appeared on October 16, 2015.

Originally I provided this post to correct an example in a previous edition of the book. Now I’m providing it to clarify that same example to a greater degree and answer reader input. The Going Overboard section on page 64 of C++ All-In-One for Dummies, 4th Edition talks about the problems that can occur when you try to stuff a number that’s too large into a specific data type. The problem with the example shown:

cout << 12345678 * 100 / 2 * 3 * 3 << endl;

is that while it does display a warning message, the warning really doesn’t get the point across. In order to see the example as originally intended, you need to change the code to read:

long MyLong = 12345678 * 100 / 2 * 3 * 3;
cout << MyLong << endl;

The code will now produce a warning and you can see why in a clearer way, just as described in the book, because the data type isn’t ambiguous any longer. In both cases you see a warning message of:

warning: integer overflow in expression of type 'int' results in '1260587804'

One of the ways to overcome this problem is to ensure that you use the correct sized variable in the first place. The following code doesn’t produce a warning message because of the use of auto (telling the compiler to choose the correct variable type automatically) and ll (telling the compiler to use a long long variable for the calculation).

auto AutoSize = 12345678ll * 100 / 2 * 3 * 3;
cout << AutoSize << endl;

A number of readers were happy that I pointed the problem out, but wanted to see a fix for the problem as well. When you run the example with the additional code, you see outputs of:

1260587804
1260587804
5555555100

Only the third answer is the correct one and it points out the need to pay attention to both warnings and errors as you code. Please let me know if you have any questions or concerns about this example at [email protected].