Disable Dark Mode for Specific Apps in MacOS X Mojave

MacOS X Mojave’s “Dark Mode” is what I prefer for most apps that I use, but for some applications I wish there was an option somewhere to disable Dark Mode for specific apps.

At the time of this writing, Apple doesn’t provide a way to choose what apps that should use the dark or light mode, it’s up to the developer to provide an option in the application’s settings, so for apps that do not have this option it’s time for a little hack.

To force an application to use the light interface mode instead of Mojave Dark Mode, quit the app in question and in a Terminal, issue the following command to get the Bundle Identifier for the app. (In this example I use the Spark Mail app from Readdle as it didn’t have an option for choosing modes at the time of this writing) :

osascript -e 'id of app "Spark"'

This command returns:

com.readdle.smartemail-Mac

for the Spark Mail app that I’m using in this example.
Copy the identifier, and issue this command to turn off Dark Mode:

defaults write com.readdle.smartemail-Mac NSRequiresAquaSystemAppearance -bool yes

Now, fire up your application again and it should run in “regular” light mode.

Note:
The command is reversible, just swap out the “-bool yes” part with “-bool no“, and you’re back to using Dark Mode.

Hope this was helpful for those out there that like myself, prefer the dark mode most of the time, but wants to be able to override the setting for specific apps that don’t play so well with the dark interface.

As always, happy hacking and have a lot of fun!

Advertisements

Free, Strong Password Generator in MacOS X

Use Keychain Access as a Password Generator

Did you know that MacOS X’s Keychain Access comes with a built-in password generator?
I usually save my passwords to iCloud via Safari’s own Keychain integration, but sometimes I need to create a new password manually, for various apps and other sites when I’m not using Safari.

If you use the built-in Keychain Access application you can manually add passwords for apps and sites. Just make sure to choose iCloud as the keychain to store passwords into.

  1. Open Keychain Access
  2. Click the + icon in the upper left corner
  3. This brings up a tool that generates strong random passwords
  4. You can choose different kinds and lengths for your passwords
Keychain Access Password Generator :)

No need for external apps to create passwords! 
All your passwords are stored in iCloud and available from your connected devices.

Sure, 1Password is a nice convenience, but for me, this works just fine and also free as in beer.

You can store Secure Notes in Keychain Access as well, something that can be useful for things like PIN codes to your credit cards, or just stuff you wish to keep private.



Add Markdown Indexing to Mac OS X Spotlight​

Markdown Indexing in OS X Spotlight Search

You can do this without disabling SIP by creating a copy of the system RichText.mdimporter, modifying its Info.plist and saving it in /Library/Spotlight.

  1. cp -r /System/Library/Spotlight/RichText.mdimporter ~/
    (This copies the .mdimporter to the root of your user home directory)
  2. You can either use an editor from the command line or go to a Finder window in your Home folder and do a “Show Package Contents” on the RichText.mdimporter file bundle to get to the Info.plist file and open it with ‘Text Edit’ or any Plain Text Editor.
Inside RichText.mdimporter/Contents/Info.plist, add: 
net.daringfireball.markdown
to the array of LSItemContentTypes in that file as shown here:
markdown-finder.png

Rename the RichText.mdimporter to Markdown.mdimporter:
mv ~/RichText.mdimporter Markdown.mdimporter

Copy the new .mdimporter to /Library/Spotlight:
sudo cp -R ~/Markdown.mdimporter /Library/Spotlight

Use the mdimport command to add it to the metadata indexing system:
mdimport -r /Library/Spotlight/Markdown.mdimporter
This command asks the server to reimport files for UTIs claimed by the listed plugin.

It should re-import the files automatically after the previous caommand, but if you wish, you can always re-index the whole drive to include the new filetype by rebuilding the whole Spotlight index:
sudo mdutil -E /

(Note: This will take some time, and is rather resource heavy…)

Now you should be good to go with .markdown files being indexed by Spotlight!

GarageBand Crashing in MacOS X “Mojave”

GarageBand 10.3.1 Crashes on startup in OS X Mojave

Yesterday I installed a fresh version of GarageBand from the Apple App Store.

I didn’t open it after the initial download, but installed IK Multimedia’s AmpliTube 4, so I could play with my newly purchased iRig HD 2.

Then, when I tried to fire up GarageBand I got an application crash notice, and was unable to use the application. Tried several times, before deciding to investigate the generated Crash Report. 

This can be found in the MacOS ‘Console’ utility, in the User Reports section.

I examined the crash log, and found this:

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes:       0x0000000000000001, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Illegal instruction: 4
Termination Reason:    Namespace SIGNAL, Code 0x4
Terminating Process:   exc handler [1282]

Application Specific Information:
dyld: launch, running initializers
/usr/lib/libSystem.B.dylib
Sandbox creation failed: Container object initialization failed.
You don’t have permission to save the file “Application Support” in the folder “Library”.
NSCocoaErrorDomain:513 
 
createDirectoryAtPath:withIntermediateDirectories:attributes:error:
WR/DST: ~/Library/Containers/com.apple.garageband10/Data/Library/Application Support

Because I installed the AmpliTube 4 application the other day, the permission errors seemed to be caused by the IK Multimedia AmpliTube 4 installer changing permissions on the following directory:

~/Library/Containers/com.apple.garageband10

The IK Multimedia AmpliTube 4 Installer puts a file link in the following location:

/Users/user_name/Library/Containers/com.apple.garageband10/Data/Library/Preferences/com.ikmultimedia.AmpliTube 4.plist

And it seems that it also changes the permissions in its parent directory (PS! I’ve changed my actual user name with “user_name” in this article):

/Users/user_name/Library/Containers/com.apple.garageband10

So I went checking the permissions with ls -la:

drwx------+   4 root    wheel    128 Nov 16 18:58 com.apple.garageband10

It looks as if the AmpliTube installer removes the regular user account from the directory permissions altogether and changes owner and group of the directory to root : wheel, and the only access granted is to the root user.

It also adds an additional ACL attribute as displayed by the + sign in this listing.

This makes it impossible for GarageBand to install the needed files into this directory as MacOS doesn’t use the root user when installing applications.

Fixing the permissions

The correct permissions for every other directory in the parent path seems to be:

drwx------    4 user_name  staff

Start by running this command to change ownership back to the defaults:

sudo chown -RH user_name:staff /Users/user_name/Library/Containers/com.apple.garageband10

You must use sudo in the command because the directory has been set to not be owned by you.

This restores ownership of the directory structure to your user name and the staff group and a new ls -la listing confirms this:

drwx------+   4 user_name  staff    128 Nov 16 18:58 com.apple.garageband10

Now you can restore the permissions on the directory to the same as for the other directories in the parent path with the chmod command. As we now ‘own’ the directory again, no sudo is needed:

chmod -R 0700 /Users/user_name/Library/Containers/com.apple.garageband10

After this, the listing displays:

drwx------+   4 user_name  staff    128 Nov 16 18:58 com.apple.garageband10

Still, there is the extra ACL attribute on the directory, not present in any of the other directories in the directory structure, so let’s remove it with the following command:

chmod -R -N /Users/user_name/Library/Containers/com.apple.garageband10

A new listing now confirms that the permissions and ACL’s on the GarageBand directory is now the same as on the others:

drwx------    4 user_name  staff    128 Nov 16 18:58 com.apple.garageband10

After launching GarageBand again, this time it starts as it should, displaying the following:

success.png

Yes, it works!

Hope this can help others experiencing same issues when launching GarageBand in MacOS Mojave or other versions and experiencing problems related to permissions in Library.

Introducing C++ Part 3 (More on pointers)

In this article “a C program” means a program written in C or C++.

Any area of knowledge can be understood at varying degrees, ranging from a cursory overview to an in-depth, intuitive understanding. That higher level of understanding for C can only be achieved with a solid understanding of pointers and the management of memory.

The key to comprehending pointers is understanding how memory is managed in a C program. After all, pointers contain addresses in memory. If we don’t understand how memory is organized and managed, it is difficult to understand how pointers work.

When a C program is compiled, it works with three types of memory:

Static/Global

Statically declared variables are allocated to this type of memory. Global variables also use this region of memory. They are allocated when the program starts and remain in existence until the program terminates. While all functions have access to global variables, the scope of static variables is restricted to their defining function.

Automatic

These variables are declared within a function and are created when a function is called. Their scope is restricted to the function, and their lifetime is limited to the time the function is executing.

Dynamic

Memory is allocated from the heap and can be released as necessary. A pointer references the allocated memory. The scope is limited to the pointer or pointers that reference the memory. It exists until it is released.

SCOPE AND LIFETIME:
SCOPE                                  LIFETIME

Global: 
The entire file                        While Application Runs

Static: 
The function it is declared within     While Application Runs

Automatic (local): 
The function it is declared within     While Function Executes

Dynamic: 
Determined by the pointers that        Until Memory is Freed
reference this memory 
(reference counted)             

Understanding these types of memory will enable you to better understand how pointers work. Most pointers are used to manipulate data in memory.

Understanding how memory is partitioned and organized will clarify how pointers manipulate memory.

A pointer variable contains the address in memory of another variable, object, or function. An object is considered to be memory allocated using one of the memory allocation functions, such as the malloc function.

A pointer is normally declared to be of a specific type depending on what it points to, such as a pointer to a char. The object may be any C data type such as integer, character, string, or structure. However, nothing inherent in a pointer indicates what type of data the pointer is referencing. A pointer only contains an address.

Faster and more efficient code can be written because pointers are closer to the hardware. That is, the compiler can more easily translate the operation into machine code. There is not as much overhead associated with pointers as might be present with other operators.

Many data structures are more easily implemented using pointers. For example, a linked list could be supported using either arrays or pointers. However, pointers are easier to use and map directly to a next or previous link. An array implementation requires array indexes that are not as intuitive or as flexible as pointers.

Dynamic memory allocation is effected in C through the use of pointers. The malloc and free functions are used to allocate and release dynamic memory, respectively. Dy‐ namic memory allocation enables variable-sized arrays and data structures, such as linked lists and queues. However, in the new C standard, C11, variable size arrays are supported.

Pointers represent a powerful tool to create and enhance applications. On the downside, many problems can occur when using pointers, such as:

• Accessing arrays and other data structures beyond their bounds

• Referencing automatic variables after they have gone out of existence

• Referencing heap allocated memory after it has been released

• Dereferencing a pointer before memory has been allocated to it
The NULL macro is a constant integer zero cast to a pointer to void. In many libraries, it is defined as follows:
#define NULL ((void *)0)

This is what we typically think of as a null pointer.

The actual internal representation of null is implementation-defined. The use of NULL and 0 are language-level symbols that represent a null pointer.

The ASCII NUL is defined as a byte containing all zeros. However, this is not the same as a null pointer.

A C-style string is represented as a sequence of characters terminated by a zero value.

The null string is an empty string and does not contain any characters.

Finally, the null statement consists of a statement with a single semicolon. As we will see, a null pointer is a very useful feature for many data structure implementations, such as a linked list where it is often used to mark the end of the list.

If the intent was to assign the null value to pi, we use the NULL type as follows:

 pi = NULL;

A null pointer and an uninitialized pointer are different. An uninitialized pointer can contain any value, whereas a pointer containing NULL does not reference any location in memory.

Interestingly, we can assign a zero to a pointer, but we cannot assign any other integer value.
A pointer can be used as the sole operand of a logical expression. For example, we can test to see whether the pointer is set to NULL using the following sequence:

if(pi) { // Not NULL, do Work; }

else { // Is NULL, exit;  }

A null pointer should never be dereferenced because it does not contain a valid address. When executed it will result in the program terminating.

NULL should not be used in contexts other than pointers. It might work some of the time, but it is not intended to be used this way.

It can definitely be a problem when used in place of the ASCII NUL character.

This character is not defined in any standard C header file.

It is equivalent to the character literal, ‘\0’, which evaluates to the decimal value zero.

Something to keep in mind (and keep sane):

int num;

int *pi = 0; // Zero refers to the null pointer, NULL

pi = #

*pi = 0; // Zero refers to the integer zero

We are accustomed to overloaded operators, such as the asterisk used to declare a pointer, to dereference a pointer, or to multiply.
The zero is also overloaded.

We may find this discomforting because we are not used to overloading operands.

Pointer to void

A pointer to void is a general-purpose pointer used to hold references to any data type.

An example of a pointer to void is shown below:

void *pv;

It has two interesting properties:

• A pointer to void will have the same representation and memory alignment as a pointer to char.

A pointer to void will never be equal to another pointer.

However, two void pointers assigned a NULL value will always be equal, because there are only one nullpointer which is shared throughout a program.

Any pointer can be assigned to a pointer to void.
It can then be cast back to its original pointer type.
When this happens the value will be equal to the original pointer value.
This is illustrated in the following sequence, where a pointer to int is assigned to a pointer to void and then back to a pointer to int:

int num;

int *pi = #

printf("Value of pi: %p\n", pi);

void* pv = pi;

pi = (int*) pv;

printf("Value of pi: %p\n", pi);

When this sequence is executed as shown below, the pointer address is the same:

Value of pi: 100

Value of pi: 100

Pointers to void are used for data pointers, not function pointers.

That’s it for now.

Until next time, Happy Hacking!

Introducing C++ Part 2

This part of the tutorial takes a look at variables, automatic conversions, memory and pointers / references.
The concepts presented may seem a bit abstract if they’re new to you but it will get more concrete once you start writing some real code.

As for types of variables this section uses only the built-in basic types such as int, double, char and pointers.

In C++ the type of an object determines the possible data that an object may contain and what operations that object may perform.
At the same time, C++ gives the programmer a lot of control in terms of what to assign to variables of different types and will let you assign types that are not directly matching through the use of automatic conversions.
It is therefore vital to understand what happens if you assign a value to a variable that it isn’t defined to use.

Conversions of basic types

You can think of conversion with basic types as being either “widening” or “narrowing”.
Widening conversions happen when you assign data to a variable that is narrower in scope than what the type is capable of handling.

An example of a widening conversion could be when you assign a integer value to a floating type variable.

int i = 10;
double d = i;

In this example variable d would have the value 10.0 after the conversion has taken place, no information is lost in a widening conversion.

Widening conversions also happen automatically when you mix integer and floating types in an expression:

double sum = i + 5.5;

Here variable i will be auto converted into the double value 10.0 before being added to 5.5, resulting in 15.5.

Narrowing conversions

double pi = 3.14159;

int i = pi;

What value does i get? It gets 3, because when we put a fractional number into an integer variable, the fractional part is truncated, as in ignored, wasted.

This is an example of narrowing conversion.
The range of values that fits in an int is more narrow than what fits in a double.

Narrowing conversions can easily be a source of errors.

In expressions containing literal values, int is the default type for numbers without decimals and double is the default for numbers containing a decimal part. This can be overridden using type specifiers following the value and will be covered later.

bool b = false;
char c = 'A';
int i = c;
b = i;

Now, what is the value of i and b?

i gets the ASCII to integer value 65, and b gets the value true.

A Boolean may only contain 0 for false or 1 for true. Any value that is not 0 will be converted to true.

Also, if we use characters in an arithmetic expression, the result is converted to an integer.

int i = 5;

double d = i;

d gets the value 5.0, as one might expect.

But what happens in this example:

int i = 123456;

short s = i;

cout << s << endl;

This leads to Undefined behavior. You can put an int into a short, but It will overflow, literally if the value of the int is larger than what a short can handle.
But the compiler accepts it, so be aware!

Memory, Pointers and References

So what are pointers and references?
They are both a way to indirectly access stored memory locations.
When we assign a value to a variable, that variable is a named memory location and internally the variable has a memory address that contain the actual data.

By using pointers and references we can access and alter these dynamic memory locations indirectly from the variable itself.

Many attempts to explain pointers using various analogies have been tried out but in my view they mostly fail to convey the intentions and usefulness of pointers in C++ and its C heritage.

All though a shallow understanding of pointers may get you by your task at hand, a deep understanding of heap and stack memory and pointers are required for understanding C and C++ on a deeper level.
Whether you want or need this “deep” understanding is off course up to you, but I recommend wrapping your head around pointers if you wish to be able to manipulate data with persistence and confidence in C and C++.

Faster and more efficient code can be written because pointers are closer to the hardware.
That is, the compiler can more easily translate the operation into machine code. There
is not as much overhead associated with pointers as might be present with other
operators.

Going deep into various uses of pointers fall outside the scope of this basic tutorial, but I encourage you to read the following
book about C and Pointers which also for the most part relates directly to C++ as well.

Understanding and Using C Pointers by Richard Reese

As your programs get more complex and include things like multi-threading and concurrency, the need to understand pointers also increases significantly as you then have to work with multiple stacks and other goodies.

Memory

Both the heap and the stack is stored in RAM.
The stack is a limited source of memory, the heap is a dynamic source of memory.
The stack is set to a fixed size, and can not grow past it’s fixed size. If there is not enough room on the stack to handle the memory being assigned to it, a stack overflow occurs.
This can happen when a lot of nested functions are being called, or if there is an infinite recursive call.

If the current size of the heap is too small to accommodate new memory, then more memory can be added to the heap by the operating system. This is one of the big differences between the heap and the stack.

A program generally works with three types of memory:

Static / Global Memory
Includes static and global scope variables. The lifetime of these variables is the whole lifetime of the application.

All functions have access to the globally scoped variables but static variables are limited to the defining functions where they are created.
Static variables are basically global variables with limited scope and there are always only one copy.
Statics / globals are useful for memory that you know you will always need and you know that you don’t ever want to de-allocate.

Stored on the stack.

Automatic / Local
Variables declared within a function. Created when the function is called and the scope and lifetime is limited to the time the function is executing.

Stored on the stack.

Dynamic
Memory is allocated from the heap and can be managed manually as nessecary (released). A pointer references the allocated memory.
The scope is limited to the pointer or pointers that references the actual memory and they exist until they are released.
Stored on the heap.

How to define and use pointers and references

The symbols * and & are the two basic symbols used to obtain pointers and create references.

A reference can be thought of as an alias for a variable. Once you bind a reference to an object you can’t re-assign it to another object.
A reference is not a type. This is a distinctive difference between references and pointers.

int i = 42;
int &r1 = i;

You can create multiple references pointing to the same variable.

int &r2 = i;
r2 = 43;

This changes the value stored by variable i.

A pointer is an actual type, and is not bound to its initial assignment in the way references are.

int i2 = 43;

int *p1 = &i // & here means "address of" (see below)

Now p1 “points to” the location of i’s data and can change the data indirectly.

p1 = &i2;

Now p1 “points to” the location of i2’s data (43). variable i is not affected.

The & and * symbols are “context sensitive”. They mean different things in different contexts.
It’s very important to be able to interpret the symbols in the correct context!

Syntax for using * and &, an overview:

int i = 42;

int &r = i; // & following a type and is part of a declaration: & means reference
int *p; // * following a type and is part of a declaration: * means pointer
p = &i; // & used in an expression: & means "address of"
*p = i; // * used in an expression: * means "de-reference" (get value of)
int &r2 = *p; // & is part of a declaration (reference), * means de-reference

You can (should) only access or de-reference a pointer that is valid, e.g. that points to an object!

Null Pointers

A null pointer does not point to any object.
You can check if a pointer is null before using it and you should always do so.

There are a couple of ways to obtain a null pointer:

int *p3 = 0;
int *p4 = nullptr;

If you include the C Standard Library (cstdlib) you can also do:

int *p3 = NULL;

The preferred way in C++11 is to use the second option:

int *p = nullptr;

Nullptr is a literal and has a type that can be converted to any other pointer type.
In the next post I’ll go into some more details of constants and how they relate to pointers and references.

 

Introducing C++ Part 1

Hello again!

This post was initially meant to go straight on with the Unreal coding standards and the way they express C++ in the engine code.

I’ve made a little detour, as this series was meant to include both those new to C++ and those new to Unreal.

I don’t feel that the Unreal coding standard is much used outside of the Unreal Engine, so in the first posts that actually involves how to write C++ I’ve chosen to use my own coding standard.

All the content from the posts that contain C++ introductory material will also be posted to the C++ page on this blog, and it is also meant to be read by those that wish to learn C++ and not necessarily the Unreal Engine as well.

This might seem a bit clunky, and indeed it is, but this is the way I’ve decided to do it.

So this post and the next few posts will mainly contain C++ until I’ve presented what I believe is a minimum of required knowledge to get started with game development using any engine with a C++ API.

So, let’s get started.

C++ Introduction

C++ is a general purpose programming language with a bias towards systems programming that supports data abstraction, object oriented programming and generic programming.
C++ is a compiled, statically typed language, which means that the compiler must know the type of every object used in a program.

C++ is used in various fields of computer science including computer games.

It received a massive overhaul with the C++11 standard that introduced many new features, such as auto type deduction, lambdas and closures.

The development continues with the C++14 standard and compiler vendors have a great deal of work to do to make their compilers support all the latest features.

What makes C++ a good choice for mobile platforms and systems programming and games is that C++ produces very effective executable code that has low power consumption on mobile platforms combined with great performance in general.

This introduction will make use of some of the new features introduced in C++11, as these features makes C++ easier to understand and more safe to use in many ways.

Most popular compilers that I know of support most of the C++11 standard at the time of this writing, at least what we’ll present in this series of posts.

Why learn C++?

There are many reasons for learning any programming language. What makes C++ a good choice for those who plan on doing programming as a part of their careers?
First of all, C++ has been used in all kinds of systems since the language became an ISO Standard in 1998 and also before that.
Many of those systems that was created back then are still in heavy use today and demands maintenance programmers to keep them up to date.
A great deal of software that we use in our day to day lives today depends on C++ to keep running.

Many new software systems created today also uses C++ because of its universal properties, making it a safe, stable and long-term alternative for cross platform development of various systems, not tied to any manufacturer and not owned or governed by any company.

For more information on C++ as a language and links to various standards, compilers and libraries, visit:
http://www.stroustrup.com/C++.html

There is a ton of valuable information on that page, covering a vast amount of topics.

How to learn C++

If you’re reading this, my guess is that you either want to learn how to use C++ in your programs.
I do not claim that the introduction offered in this series of posts will be anywhere near sufficient to make you a C++ developer.

This is only meant as a starting point for learning more of the intricate nuances that C++ programming is all about.

I want to introduce you to some of the concepts that I found tricky to wrap my head around when I started learning about the C++ programming language, before the YouTube age and the massive amount of learning opportunities available today.

The fact that the sources for learning C++ has become so many and so diverse actually doesn’t make it that much easier, because you have to know what sources to trust as being good and that in it self is a rather hard task if you don’t know what to look for!

I’ve seen both paid and free resources available for learning C++ that range in quality from down right pathetic and plain wrong to excellent and well worth your precious time. Just remember: What you pay for is not necessarily what you get.

In these posts I’ve tried to extract knowledge from various books I wish I had when first learning C++, and turn it into easily digestible bits of information.

Some of the books I highly recommend and that I’ve used as inspiration for writing this series include:

Programming – Principles and Practice Using C++ 2nd Edition by Bjarne Stroustrup et. al
C++ Primer, 5th Edition by Lippman, Lajoie and Moo
Think Like a Programmer – An Introduction to Creative Problem Solving by V. Anton Spraul
Understanding and Using C Pointers by Richard Reese
Effective Modern C++ by Scott Meyers
Safe C++ by Vladimir Kushnir
The C++ Programming Language 4rd Edition by Bjarne Stroustrup

These are all books that are verified and accepted as good learning material by the C++ community at large and is a safe bet if you want to know more about the vast areas of programming and to find specific information about using C++ in the best ways possible.

How to structure the material

I’ve seen many attempts to divide the beginning concepts of C++ into logical parts that makes it “easy” or easier to understand.
Some introduce functions before references and pointers, some introduce classes before general compound types and some choose to ignore the concepts of memory, pointers and references all together in the beginning chapters.

To me that’s all a bit too abstract. I prefer a more direct path.
Before learning to use functions I feel that it is imperative to know something about constants and references, as this will get more important when trying to write various functions that can both manipulate its arguments directly or being denied to change its
arguments as a whole.

I also feel that even though Object Oriented Programming (OOP) has many important uses it is also maybe the most abused concept in modern programming. This is a direct consequence of pure OOP languages such as Java that requires you to create a class just to do a simple “Hello World!” program.

In C++ OOP is an option but not a requirement. You can choose when to start introducing objects into your code and if you can do without it, why complicate matters if it doesn’t lead to anything other than unnecessary complexity?

Well, enough said.
Let’s get on with the actual introduction to programming in C++.

Variables and Basic Types

C++ defines a set of built-in primitive types that include the arithmetic types and a special type named “void”.
Void will be described later when we start talking about functions.

Arithmetic types are divided into “integral” types (numbers) and also include characters (char), like ‘A’ and Boolean (true/false) and floating point types (numbers with a fractional part), like 3.14.

Before continuing on, let’s detour into how these types are stored in a computer.

How machines represent the built-in types

As many knows, computers store data as a sequence of bits. each holding either the value 0 or 1. This is referred to as the binary number system.

That is a stream of bits, like 0001110011001110 …

To keep track of the stored values in memory, computers group chunks of “bits” and the smallest chunk of addressable memory is referred to as a “byte” and is usually made up of 8 bits.

The computer’s basic character set is used to define the size of a byte and in C++ a byte has “at least” as many bits needed to hold a character.
Most machines operate with 8 bit bytes and the ASCII basic character set.

The basic unit of storage is called a “word” and consists of a small amount of bytes grouped together. On 32-bit systems this is usually 4 bytes (4 * 8 = 32) and on 64-bit systems it is the double of that, 8 bytes (8 * 8 = 64).

You can visually represent a word like this:

byte-ordering

There is also a concept of Big-Endian and Little-Endian that describes the order of the bytes in memory and in transmission over a digital link. This is not something you need to concern yourself with when starting out, but it is an important topic later on.
The concept of “Big-Endian” vs. “Little-Endian” can be further investigated here:

https://en.wikipedia.org/wiki/Endianness

The following is a short description of the various arithmetic types.

C++ is designed to let the programmer exploit hardware specific optimizations and therefor provides a number of different types to squeeze the most out of any given hardware platform.

In practice, and when beginning to learn about C++, don’t get caught up in all the details.
The provided information is only provided for the sake of completeness.

Characters

There are a few different character types available, to accommodate for various needs and extended character sets.
The basic character type is called char and big enough to hold numerical values corresponding to the machine’s basic character set.
In addition there is wchar_t, char16_t and char32_t, all used for extended character sets.

char16_t and char32_t are intended for Unicode characters. Unicode is an example of an extended character set.
wchar_t is guaranteed to be large enough to hold any character in the machine’s largest character set, whatever that may be.

The character types has corresponding numerical values that maps to the different characters thay can represent,
like the character ‘A’ correspond to the decimal number 65, ‘B’ is 66 and so on.

Floating Types

These represent single (float), double (double) and extended precision (long double) values.
The standard only specifies a minimum number of significant digits but most compilers provide more precision than the required minimum.
Typically a float is represented in 32 bits giving it around 7 significant digits of precision, a double is stored in 64 bits with around 16 digit precision and a long double is stored in either 96 or 128 bits. The precision of all floating types are hardware dependent and the use of long doubles are largely dependent on the given hardware support.

Signed and Unsigned Types

Except for bool and the extended character types, the integral types may be “signed” (can contain negative values) or “unsigned”
(can only contain values 0 or above).
One way to remember this is that to use a negative number, you have to use a sign (the – sign), hence you need a signed type.

The types int, short, long and long long are all signed types and can contain values below 0. (negative numbers).

We can get the corresponding unsigned type by adding the word “unsigned” before the name of the type, as in unsigned int.
In the case of int you can use the abbreviated form of just unsigned, as in:

unsigned count = 0;

Signed and Unsigned Characters

To complicate things a bit more, there are three different types of characters.
char, signed char and unsigned char are all distinct basic character types.
There are actually only two representations of characters in memory, signed or unsigned, but the plain char uses one of these depending on the compiler you use.

The 8-bit unsigned char can hold values from 0..255 (inclusive) while the signed char can hold values from -127..127.
Most modern machines use representations that allow -128..127, but the standard only guarantees -127..127 (inclusive).

What to use when?

As mentioned earlier, all though C++ provides a staggering amount of arithmetic types, you’ll find yourself using only a handful of these on a day to day basis.

Some rules for what to use when can include:

  • Use an unsigned type when you KNOW that the values should never be negative
  • Use regular int for integer arithmetic. (short is usually to small and long usually has the same size as int)
  • Use long long if you KNOW that the value will exceed the minimum guaranteed size of an int
  • Use double for floating point computations
  • Don’t use char or bool for arithmetic expressions. Only to hold characters or true / false respectively

Next time I’ll cover some information regarding type conversion!

Stay tuned.