C++ FAQ

Frequently Asked Questions for the C and C++ programming languages.

What is an iterator?

Iterators provide a unified API for accessing different containers. On the surface, they work similar to pointers: std::vector<int> vec { 1, 2, 3 }; auto it = vec.begin(); // gives us an iterator which points to '1' it++; // start now points to '2' it++; // start now points to '3' std::cout << *it << '\n'; // prints '3' TODO Noncontiguous containers (std::list): linked list isn’t a contiguous sequence, so it’s impossible to relay on pointers for iteration instead you should provide an iterator that performs the same arithmetic operations as a pointer would do....

About this site

TODO

How do I enable compiler warnings?

For gcc and clang users: Add -Wall -Wextra to your compilation flags. Other useful options include: -Werror: treats warnings as if they were errors -pedantic: generates warnings if you use any language extensions -Wno-x: disables warning x, e.g if the compiler gives you a -Wunused-variable warning, you can turn it off with -Wno-unused-variable (Note that, contrary to what the name -Wall may imply, this does not enable all warnings, but it does enable most of the important ones....

What are ‘Include Guards’ and #pragma once?

Include guards, or sometimes called macro guards, header guards, or file guards are a common C/C++ idiom that allows including a header file multiple times safely. The non-standard preprocessor directive #pragma once is an almost equivalent alternative to this idiom. The Problem The preprocessor directive #include effectively copies the named header into our source file. If we #include a header file more than once, this will result in redefinitions and possibly compiler errors....

What are ‘Unspecified’ and ‘Implementation-Defined’ behavior?

Unlike undefined behavior, unspecified and implementation-defined behavior occur all the time in a normal C++ program. Making use of unspecified/implementation-defined behavior is unavoidable, but relying on specific behavior can be fatal. The C++ standard does not specify what happens in every scenario, so the implementation has the freedom to implement behavior, constants, macro definitions, and more in multiple possible ways. Unspecified Behavior unspecified by the standard is not necessary to document, but still valid....

What are fixed-width integers?

Fixed-width integers are integral types with a fixed number of bits. The C++ standard only specifies a minimum byte count for types such as short, int and long. Fixed-width integers guarantee a specific size, but their use can have an impact on portability, since they are not supported by all platforms. Fixed-width integer types These can be used by including <cstdint>. The intX_t types are signed integers with exactly X bits....

What is ‘Undefined Behaviour’?

Undefined Behaviour (also known as UB) occurs when you violate certain language rules. These rules include (but are not limited to): dereferencing a null pointer, signed integer overflow, accessing through a dangling reference, or accessing through an unaligned pointer. When undefined behaviour occurs, the C and C++ standards do not place any restrictions on what your program might do. In other words, your program may crash, or continue execution, or call some seemingly unrelated piece of code, or print 42 and open xkcd in your web browser....

What is a ‘Member Initalizer List’ and why should I use it?

Constructors in C++ are used to initialize the data members of a class. First, it’s important to understand the terminology: struct wrapper { int value; wrapper(int v) : value{v} { } }; Our class wrapper has a constructor, consisting of four parts: the class name wrapper the parameter list int v in parentheses the member initializer list value{v}, separated by a : from the parameter list the constructor body {}, which is empty in this case In most other languages that have classes and constructors, the initialization simply takes place in the constructor body....

What is decay and array-to-pointer conversion?

When we call functions in C++, our arguments may need to undergo type conversions. For example, we can call a function that takes an int with a const int argument, which copies its value. For parameters which are passed by value, some of these conversions rules are called decay. They are called decay because in most cases, some type information is lost, such as the size of an array or the const qualifier in our example....

Why is using namespace std considered bad practice?

Consider this code: #include <iostream>#include <algorithm> using namespace std; int swap = 0; int main() { cout << swap << endl; // ERROR: reference to "swap" is ambiguous } Here, the compiler throws an error because it doesn’t know whether you refer to your swap global variable, or the std::swap function inside the <algorithm> header. That is to say, using namespace is considered bad practice because it leads to name collisions, and it also makes your code less clear....