Click for commercial
Scott Meyers Training Courses
Each of the following presentations is lecture-only (no hands-on programming) and is compiler- and platform-independent. Listed lengths are approximate.
Note that material from any of Scott's longer courses (i.e., one or more days) can also be extracted and presented as a short course.
- CPU Caches and Why You Care
No matter what programming language or technology you use, if your software fails to make effective use of the underlying CPU caches, your system's performance will suffer. A lot. This session provides a wide-ranging overview of CPU caches, how they operate, and how that affects high-level decisions on things like data structures and traversal strategies. Both single- and multi-threaded execution are considered. Specific topics include different cache types (data, instruction, TLB); private and shared caches; cache lines and speculative prefetching; false sharing; and cache-friendly program organization, data structures, and traversal strategies. If you care at all about performance, the information in this talk is essential. Length: 1.5 hours.
- The C++11 Memory Model and Why You Care
In 2004, Scott and Andrei Alexandrescu coauthored an article about why it was not possible to write a safe implementation of double-checked locking in standard C++. Between compiler optimizers performing code motion and processors reordering loads and stores, there was no way to prevent transformations that could cause safe-looking source code to yield incorrect runtime behavior. But that was for C++98, which, because it had no concept of threads, had no memory model, so it offered no guarantees regarding the visibility of reads and writes across threads. C++11 does have a memory model, and the changes to the language and library are significant. Sequence points no longer exist, having been replaced with the "sequenced before" and "happens before" relationships. Atomic types offer memory visibility guarantees not offered by non-atomic types, and compilers must generate code that respects these guarantees. This talk addresses a variety of topic related to the C++11 memory model and its practical implications, including compiler optimizations, memory access reorderings, "sequenced before" and "happens before" relations, atomic types, double-checked locking, and how these relate to both correctness and performance. Also, because it's pretty much obligatory in this kind of talk, it examines the potentially confusing relationship between atomic and
volatiletypes. Length: 3.0 hours.
- Move Semantics, Rvalue References, and Perfect
Forwarding in C++11
Probably the most pervasive new feature in C++11 is move semantics, which allows compilers to replace expensive copy operations with inexpensive move operations. This talk explains the motivation for move semantics, the conditions under which compilers can replaces copies with moves, and how programmers can control the process. It also describes rvalue references, the new language feature on which move semantics is based, as well as perfect forwarding, another technology based on rvalue references that enables move semantics to be more widely applied than would otherwise be possible. Length: 1.5-3.0 hours, depending on the depth of the treatment.
- Adventures in Perfect Forwarding in C++11
The thing about perfect forwarding (introduced in the short course on move semantics and rvalue references) is that there's both less and more to it than the name suggests. Perfect forwarding isn't perfect, for example: there are types that cannot be perfect-forwarded. Such imperfections have implications for both those who specify interfaces as well as those who use them. Perfect forwarding is implemented via function templates with parameters declared to be of type
T&&. Such parameters are treated specially during type deduction, which is fine, unless you want to specialize the templates. The only parameter type that gets the special treatment is
T&&, so you can't overload on something like
T*&&to "partially specialize" for pointer types. Achieving the effect of such specialization calls for more sophisticated techniques. Perfect forwarding complicates use of the pImpl idiom, because the template instantiation mechanism typically wants all the template code in the header file, yet the use of pImpl is motivated by the desire to avoid having to do that. This talk begins with a very brief review of perfect forwarding, then proceeds to an examination of the practical issues such as those above that arise when you try to put perfect forwarding into day-to-day use. Length: 2.0 hours.
- Double-Checked Locking, Threads, C++ Compiler Optimizations, and More
The Double-Checked Locking Pattern is a common approach to efficient lazy initialization. Unfortunately, it's not reliable in C++ in threaded systems, it can fail for different reasons in uniprocessor and multiprocessor environments, and there's no portable way to make it reliable. Every C++ programmer needs to understand why this is the case, because it affects the very core of software development: code generation and program execution. This talk takes a deep look at code generation, compiler and hardware optimization, sequence points, "observable behavior," the significance of "volatile," memory coherency problems, and memory barriers. It concludes with suggestions for C++ programmers who want the efficiency of lazy initialization, but who value correct program behavior even more. Length: 1.5 hours.
- Real World C++
When Scott started consulting on C++ projects, he figured his biggest challenges would center on the proper use of language features. He was so naive. Over the years, he's discovered that the biggest obstacles to success in C++ involve a little C++, a fair amount of language-independent software engineering, and a healthy dose of decent management. This talk presents over a dozen specific guidelines that Scott has found to significantly improve the chances of success on real software projects in C++. Some guidelines focus on specific language issues (e.g., casts, virtual destructors), while others focus on broader matters (e.g., the need to embrace abstraction, the importance of specifications, the need to perform retrospectives). Compared to Meyers' usual talks, this seminar is less intensively technical, but it covers a broader array of issues, and it is definitely about C++ software development. Most of the material in this talk is excerpted from Scott's longer courses, notably Better Software — No Matter What and Effective C++ Programming. Length: 1.5 - 3.0 hours.
- Coupling, Reuse, Testability, and C++
This course examines how these topics relate to one another. What leads to compile-time coupling? What leads to link-time coupling? How can such coupling be broken? How does coupling affect testability? How does it affect reuse? Is is possible to minimize coupling and maximize reuse? In general, what are the trade-offs among these topics? Much of the material in this talk is based on ideas in John Lakos' book, Large-Scale C++ Software Design. Length: 1.5 hours.
- The Wonderful World of
This talk examines "const" from just about every angle you can think of: const objects, const parameters, const member functions, const return types, conceptual constness, bitwise constness, const and mutable, casting away constness, const and typedefs, const and pointers, const and type conversions, const and arrays, const and string literals, const and constructors/destructors, and const and efficiency. Length: 2.0 hours.
- C++ Under the Hood
An examination of how the fundamental language features are implemented. A primary goal is to demonstrate that programmers pay no penalties for using C++ instead of C, that they actually gain flexibility, maintainability, and greater potential for reuse through the language's support for abstraction, encapsulation, and inheritance. Specific language features to be discussed include classes, member functions, virtual functions and virtual calls, new and delete, inlines, and inheritance. Attendees are encouraged to bring questions about the costs or likely implementation strategies for any feature in the language. If desired, this seminar can also cover information on how to control code bloat when using templates. Length: 1.5 hours without coverage of templates and code bloat; 2.0 hours with such coverage.
- When C++ Hits the Hardware
This class addresses two issues of particular interest to developers of embedded systems, but the material should be of interest to everybody working with C++. First, it examines the parts of programs that don't change during execution, i.e., the parts that could be burned into ROM. Second, it describes an elegant approach to modeling memory-mapped IO that provides a natural interface for users, great flexibility for implementers, maximal efficiency (in both size and space), and compile-time prevention of common client errors. The technique is based on a combination of templates, classes, inline functions, placement and custom new (without requiring dynamic memory allocation), references, bit operations, volatile memory, private member functions, and reinterpret_casts, but the generated code should be as good as that produced by the most hardcore hardware hacker. Length: 1.5 hours.
- Programming with C++ Exceptions
Writing exception-safe code -- code that avoids resource leaks, corrupted data structures, and violated program invariants -- calls for coding techniques that are fundamentally different from those employed in exception-unsafe code (including C). This seminar explains what exception safety is and why it's important; defines the different levels of exception safety and explains when each is appropriate; and introduces the programming tools and techniques used to achieve exception safety. Participants will collectively examine samples of exception-unsafe code, identify potential exception-safety problems, and develop exception-safe rewrites. In addition, the seminar covers information on the behavior of C++ exceptions themselves, e.g., the rules governing their creation, cost, lifetime, propagation, etc. Length: 3.0 hours.
- Using the STL Efficiently
The STL is easy to use, but, unfortunately, it's also easy to use inefficiently. This seminar, based on material in Scott's book, Effective STL, describes proven ways to make more efficient use of STL components. Topics covered include the importance and behavior of remove; why range member functions are preferable to iterative use of their single-element counterparts; how to efficiently erase elements from containers under a variety of conditions; the importance of using reserve for vectors and strings and how "the swap trick" can be used to eliminate excess capacity that can result; why and how to prefer sorted vectors over sets, multisets, maps, and multimaps; an overview of the nonstandard hashed containers, including those in TR1; how to choose among sorting and partitioning algorithms; why to prefer member functions over algorithms with the same names; and why to prefer function objects over function pointers as algorithm parameters. Length: 3.0 hours.
- An Overview of TR1
TR1 -- "Technical Report 1" from the Library Subcommittee of the C++ Standardization Committee -- specifies 14 new kinds of functionality that augment that in the C++98 standard library. This seminar gives an overview of the contents of TR1, explains where you can go to get useful information about it (including the software itself), and shows examples of the most widely useful functionality, including shared_ptr, hash tables, regular expressions, fixed-size arrays, and tuples. If you program in C++ and are not familiar with TR1, you need the information in this course. Length: 2.0 hours.
- Using and Controlling new and delete
All nontrivial C++ software makes use of heap memory, so it's crucial that C++ programmers know how to use new and delete correctly. For some types of software, it's equally crucial that programmers understand how to control the behavior of new and delete. This talk discusses the various forms of new and delete (e.g., global, class-specific, versions with extra parameters, placement versions, nothrow versions), how they control memory management and object initialization, the conventions they follow, and why and how programmers can take control of the behavior of operator new, operator new, operator delete, and operator delete. The material in this seminar complements the material in the STL Allocators short course. Length: 3.0 hours.
- STL Allocators
Allocators are responsible for handling all dynamic memory allocation and deallocation in STL containers. This talk explains the conventions and restrictions governing allocators, describes how they differ from
free, exposes insights such as that most containers never ask their allocator types for memory, and identifies purposes for which allocators are and are not well suited. It ends with an overview of the source code for a sample allocator. The material in this talk complements that in the Using and Controlling New and Delete short course and is largely based on Scott's book, Effective STL. Length: 1.5 hours.
- Enforcing Code Feature Requirements in C++
Functions often depend on particular behavioral characteristics (features) of code they invoke. For example, thread-safe code must invoke only thread-safe code if it is to remain thread-safe, and exception-safe code must invoke only exception-safe code. This talk describes a technique based on template metaprogramming that enables the specification of arbitrary combinations of user-defined code features on a per-function basis and that detects violations of feature constraints during compilation. The technique applies to member functions (both nonvirtual and virtual), non-member functions, and function templates; operators are excluded. The described implementation is proof-of-concept and isn't ready for production use, but both what can be done as well as how it can be accomplished should be of interest to every advanced C++ software developer. Length: 1.5 hours.
- The Keyhole Problem
Software too often imposes gratuitous restrictions on how we see or interact with the world — forcing us to experience the world through the keyhole of a door. The Keyhole Problem arises every time software artificially restricts something you want to see or something you want to express. If you want to see an image, but your image-viewing software artificially restricts how much of that image you can see at a time, that's the keyhole problem. If you want to specify a password of a particular length, but your software says it's too long, that's the keyhole problem. If you want to type in your U.S. telephone number, but your software refuses to let you punctuate it in the conventional manner with a dash between the three-digit prefix and the four-digit exchange, that's the keyhole problem. This talk — which applies to software written in any language — discusses what "keyholes" are, why they are worth caring about, and suggests ways to design and implement software containing as few keyholes as possible. Length: 1.5 hours.
For additional information on any of these courses, or to discuss the creation of new courses to meet your specific needs, contact Scott directly.