DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
C++0x
1. Practitioner Debasish Jana
Workbench Editor, CSI Communications
Exclusive Interview with
Prof. Bjarne Stroustrup, Creator of C++
Prof. Bjarne Stroustrup is the creator of the most popular programming language, C++. He is the living
legend, he is the maestro. His book “The C++ Programming Language” is the most widely read book of its kind
and has been translated into 19 different languages around the world. In addition to his five books, Stroustrup
has published more than a hundred of academic and popular papers.
Bjarne was born in Aarhus, Denmark in 1950. He received his Candidatus Scientiarum (Master’s degree) in
Mathematics and Computer Science from the University of Aarhus, Denmark in 1975. He obtained his Ph.D. in
Computer Science from University of Cambridge, England in 1979 for work on the design of distributed systems.
He designed and implemented C++ while a researcher in AT&T Bell Lab’s Computer Science Research Center
and was the head of AT&T Lab’s Large-scale Programming Research department, from its creation until late
2002. Stroustrup was elected member of the National Academy of Engineering in 2004.
He is a Fellow of the ACM and an IEEE Fellow. He currently works at Texas A&M University, United States, as a
Distinguished Professor where he holds the College of Engineering Chair in Computer Science.
CSI Communications | August 2011 | 22 www.csi-india.org
CSIC August 2011.indd 22 8/6/2011 12:45:45 PM
2. Part 3 of 3
C++0x Technicalities and Intricacies
Prelude
C++0x (pronounced “see plus plus oh ex”) is the new standard for the C++ programming language (earlier
and existing standard is C++98 or ISO/IEC 14882, published in 1998 and minor amendment was done in 2003
as C++03). In their March 2011 meeting, the C++ Standards Committee voted C++0x (N3290) to Final Draft
International Standard (FDIS) status. The final specification is expected to be published sometime in mid-2011
The implementation of the new standards (to be known as C++11 or C++2011) is already well underway in the
GCC, Visual C++, and other C++ compilers.
C++ is a general-purpose programming language with close-to-machine fundamental semantics, suitable
for kernel and systems programming with a mission of being a better C, supporting data abstraction, object
oriented programming and generic programming. C++ is used in a very wide range of applications and for
systems programming: http://www2.research.att.com/~bs/applications.html. C++0x aims to improve C++ as a
language for systems programming and library building with ease of learning while at the same time remaining
fully backward compatible. C++0x is going to have nice features like uniform initialization, move semantics,
lambda’s as first-class elements, automatic type deduction, and a simplified for statement. Also there are atomics,
a defined memory model, and support for thread-level concurrent programming.
On concurrency support in C++0x do the new standards aim to cope up with this?
Prologue (Debasish Jana): With heterogenerous and varied Bjarne Stroustrup: We have to distinguish between the various
platforms (both hardware architecture and operating systems), application areas: Concurrency is used in many forms and in
writing portable programs remains a challenge. As of C++98 many contexts. For example, C++11 provides direct support for
and its ammedment as of C++03, C++ faced varied portability system-level concurrency, but does not provide direct support
issues. For example, size of integer (int) type data was 2 on 16-bit for web development; that’s the domain for libraries and domain
machine, 4 on 32-bit machine, 8 on 64-bit and so on. Also, for specific languages. I would have liked to provide standard support
character strings, the size of a single character could be one or for distributed computing, but we did not have the resources to
two bytes depending on the language of character set (English, get such facilities into the standard, so (as ever) C++ provides
Japanese) it represents. Added to that, for parallel processing, support for programming in a single address space. What’s new is
concurrency support, threads, semaphores used to depend on that the support for threads, locks, etc. is standard and type safe.
infamous posix libraries or platform dependent operating system Also, we now have a precise specification of the memory model.
specific calls making a source code written in C++ not portable There is also a set of primitives for lock-free programming so that
across platforms. One way to make portable code was to define programmers can build their own libraries to support alternative
platform specific calls within the block of #ifdef for example views of concurrency.
#ifdef WIN32 Most of the concurrency parts of the new standard are already
// win32 specific code available today.
#else
#ifdef LINUX ... C++11 provides direct support for system-
//linux specific code
level concurrency, but does not provide direct
#endif
#endif support for web development; that’s the domain
Also, web support, multicore architecture support all cause for libraries and domain specific languages.
problem to support portability.
Debasish Jana: Earlier C++ standards did not have language level On threads in C++0x
portable support for concurrency, multicore, web development, how Prologue (Debasish Jana): In C++98 and C++03, threads were
CSI Communications | August 2011 | 23
CSIC August 2011.indd 23 8/6/2011 12:45:47 PM
3. supported not as part of the language but part of the operating Bjarne Stroustrup: Obviously, we must avoid data races in both
system calls available with the operating system specific libraries. cases. My best advice is to avoid shared data whenever possible
Multithreading and concurrency helps to run multiple portions and use locks when we have to share data. So, rely on data passed
of code in parallel to the execution of the other portions of code. as parameters to threads, local (stack) memory, and non-shared
In case we have the hardware support for multiple processors free store. When that’s not feasible, the standard provides
(multicore) or just a single CPU (single core), then in the former mutexes, locks, and condition variables, so that all the usual
case, the code can run in parallel in true sense, and in later case, techniques can be used. For example:
oerating system uses a concept of time sharing where mutiple X my_data;
tasks are interleaved within same processor to offer a pseudo mutex my_mutex; // mutex used to avoid
form a multiple tasking. Whatever be the case, we have to identify // data races for my_data
the function that should run concurrently as part of a thread void my_fct() { // potentially running in
executing in parallel. // several threads
lock lck(my_mutex); // acquire mutex
C++ supports threads in a single address space. my_data.foo(); // use the shared data
} // lck’s destructor implicitly
Anything involving multiple address spaces // releases my_mutex
must be done with higher-level libraries that We use RAII (“Resource Acquisition Is Initialization”) to minimize
are not part of the standard. errors leading to non-released resources. The standard provides
several kinds of mutexes (e.g. recursive mutexes and timed
Threads are considered as lightweight process, where a two mutexes) and an operation to simultaneously acquire several
threads share the same address space within the parent process. mutexes.
This means, the code area, heap area, global memory area are Epilogue (Debasish Jana): To avoid racing and surprises in
all shared, and the stack area are different for each thread so as accessing shared variables, any access (read or write) to the
to separate the execution control and local data that gets stored shared variables must be mutually exclusive so that no two
within stack. threads can access the same variable in read-write mode. This is
Debasish Jana: How will the new C++ support threads running on done by locking through mutex semaphores. Earlier, semaphore
different address spaces and on different processors in muticore support was through the operating system specific library, now
machines? Will we be able to run multicore threading yet portable the support is given in the language level for increased and
across platforms? enhanced portability across platforms.
Bjarne Stroustrup: C++ supports threads in a single address
space. Anything involving multiple address spaces must be done C++ has a bias towards systems programming:
with higher-level libraries that are not part of the standard. There It combines a direct and efficient model of
is no standard mechanism for exchanging data between threads
in different address spaces. For that, you’ll have to use one of the the machine with very flexible and general
existing inter-process communication libraries and probably each abstraction mechanisms, allowing zero-
system’s native processes. overhead abstraction.
On thread-safe synchronization in C++0x
Prologue (Debasish Jana): In C++98 and C++03, threads running On passing value or exception from dying thread in
in same address space share the global data area of the parent C++0x
process. As such, all static data and shared variables are shared Prologue (Debasish Jana): The execution of a thread may
across threads of same process as well. This puts a challenge on terminate normally when the execution reaches the end of the
the synchronization of the shared data, because while one thread function, irrespective of the execution point of the other threads.
may try to acess the shared variable, the other thread may try to The scheduling of threads is always unpredictable, as it depends
modify this, resulting in a race condition. on the operating system, thus, we have no clue to know how far
the thread has executed. The thread may not have been started, or
My best advice is to avoid shared data whenever may have been midway during execution, or it could have finished
normally, or worst case, the thread has terminated abnormally
possible and use locks when we have to share when the thread has been abruptly stopped.
data. So, rely on data passed as parameters to
Debasish Jana: If a thread abnormally terminates because of a
threads, local (stack) memory, and non-shared runtime exception, how do the other threads know about this and
free store. cope up (in new C++0x standard)?
Bjarne Stroustrup: You can “transfer” a value or an exception
Debasish Jana: How will the new standard deal with synchronization from one thread to another. The mechanism for that is called a
of thread-safe dynamic concurrent initialization and cleanup of static future. This is the one C++0x mechanism that is not part of the
variables as shared variables? conventional threads and locks system level of concurrency.
CSI Communications | August 2011 | 24 www.csi-india.org
CSIC August 2011.indd 24 8/6/2011 12:45:47 PM
4. Say that I have a task (function or function object) f that I’d like to late, making it hard to give decent diagnostics, but at least they
invoke with arguments x1 and x2 so that it will run concurrently are caught before the program starts running.
with my thread. This can be done like this: C++11 does improve the support for generic programming
future<double> x = async(f,x1,x2); // run f(x1,x2) concurrently significantly despite our failure to address that specific important
// do other work problem.
double d = x.get();
Here, I have assumed that f returns a double; if it doesn’t, the code On language features and design philosophy of C++ in
won’t compile. The get() potentially waits for the task to finish general
and if f fails and signals that failure by throwing an exception, then Debasish Jana: Every language has its own philosophy which
the call to get will throw that exception. The async function is one also evolves and adapts over time. However, C++ preaches about
of the ways that the standard library provides to invoke a function philosophy very tightly blended in the applicability of the language.
to run in a separate thread and return its value or exception to a That philosophy includes more object orientation, also procedural,
caller. more so in terms of programming with proper algorithmic footprint.
Your views on that.
When I write a program of any size it is not Bjarne Stroustrup: Language features exist to support design
philosophies. However, a language designer cannot anticipate all
a choice of OOP vs. GP vs. C-style; for the programmer needs, so a language design has to aim for generality.
most appropriate abstractions and the best In particular, I am strongly against deliberately crippling features
performance, I have to use a set of features to prevent “bad code.” In general, we don’t know what will be “bad
code” in a few years or in an unanticipated application area. The
and techniques that cross those classification advantage of specialized languages is that their designers can
boundaries. make far stronger assumptions about the use of their languages
and the background of their users than designers of general-
On allowed types in templates in C++0x purpose languages. What I say on this topic is primarily relevant
Prologue (Debasish Jana): Templates are nice things in C++ to to general-purpose languages and in particular to C++. C++ has
provide generic programming support. Through template, we a bias towards systems programming: It combines a direct and
provide parameterized classes or functions so that we write the efficient model of the machine with very flexible and general
class or function be supported for a variety of data types, and abstraction mechanisms, allowing zero-overhead abstraction.
the data type passed as an argument. For example, to support
vector<int> or vector<char>, we write the class vector as a ...the main point is that we cannot classify this
parameterized class or template. However, in many cases, we see program as “object oriented”, “generic”, or
that the generic program may fail to a specific case because of the
fact that a particular function or operator is not provided for that “traditional” even though it uses the classical
particular type making it fail to support for a particular type. characteristic language features for using each
Debasish Jana: One major problem with generic programming is “paradigm.” What we see here is a synthesis
that the templates don’t tell about the permissible or allowed types that elegantly and efficiently incorporates all.
that can be passed. Any suggestion on that?
Bjarne Stroustrup: We worked hard to solve that problem, but I want to get beyond the “multi-paradigm”/hybrid view of C++.
didn’t come up with a sufficiently good solution. We need an When I write a program of any size it is not a choice of OOP vs.
easier-to-use and faster-to-compile design than the one we had GP vs. C-style; for the most appropriate abstractions and the best
for C++0x. I’m trying to do a thorough re-think of that, but I’m not performance, I have to use a set of features and techniques that
ready to commit to even a definite direction for a design. Look for cross those classification boundaries. I still don’t have a snappy
my research papers over the next couple of years. I suspect that label for what I do, but the central idea is to provide a direct and
semantic requirements will play a bigger role than they did in the efficient mapping of my application ideas to machine resources.
past. That was also the aim of the pioneers of object-oriented and
generic programming; it was only later – in the hands of less
One of the historic strengths of object- thoughtful and less experienced people – that the distinctions
oriented programming was exactly that it between techniques became characterized in terms of language
was an attractive label – sometimes hiding features and simplistically discussed in terms of good vs. bad.
irreconcilable differences among its proponents. I’m working on getting from philosophical statements like those in
the previous paragraph to practical rules and good examples. You
Please also remember that even though the error messages can actually find a fair bit of that in TC++PL3, PPP, and my articles
caused by mistakes in generic code can be spectacularly bad, and interviews about style over the years, but I must develop a
templates support real-world uses of generic programming clearer and more consistent statement and find a simple label.
rather well – spectacularly well in some cases as compared to One of the historic strengths of object-oriented programming
alternatives in other languages. Also, type errors may be caught was exactly that it was an attractive label – sometimes hiding
CSI Communications | August 2011 | 25
CSIC August 2011.indd 25 8/6/2011 12:45:47 PM
5. irreconcilable differences among its proponents. specifying the sorting criterion. However, the main point is that
we cannot classify this program as “object oriented”, “generic”,
So, consider the following C++11 program:
or “traditional” even though it uses the classical characteristic
struct Point { // traditional C-style struct language features for using each “paradigm.” What we see here is
int x, y; a synthesis that elegantly and efficiently incorporates all.
// …
On auto detection of a type from an initializer
};
Prologue (Debasish Jana): C++ is based on strong type theory
struct Shape { // traditional OO abstract base class
where every data defined within the program must have a valid
virtual void draw() = 0; // pure virtual function
type with strict compile-type binding. For example, we have
virtual void move(Point to) = 0;
virtual pair<Point,Point> box() = 0; // bounding box int i = 5;
// … to declare and define a variable i as integer (int) initialized to 5.
virtual ~draw() {};
}; We may have void * pointer which can point to any typed pointer,
// classical class hierarchy for example,
class Circle: public Shape { char ac[10]; // array of 10 characters
public: void *ptr = NULL; // placeholder pointer
Circle(Point,int); ptr = (char *) ac; // ptr points to start address of ac
// data, overriding functions, …
}; I think we should look serious at a simpler-to-
// classical class hierarchy
class Triangle: public Shape {
use and simpler-to-implement concept design
public: as the premier way of improving our support for
Triangle(Point,Point,Point); generic programming.
// data, overriding functions, …
};
We may have also a superclass (or base class) pointer pointing to
constexpr Point Origo {0,0};
a subclass (or derived class) pointer, such as,
constexpr Point P2 {50,100};
constexpr Point P3 {100, 30}; class A{};
// classical parameterized container type class B: public A{};
vector<Shape*> vs { A *pa;
new Circle{Origo,20}, pa = new B(); // left side is a base class pointer
new Triangle{Origo,P2,P3}, // right side is a derived class pointer
new Circle{{-10,200},20}, C++0x is bringing out a nice feature of deducing of a type from
new Triangle{{-400,0},P2,{-200,200}}, an initializer. Earlier, in C (but not ISO C++), we had the concept
// … of “implicit int,” i.e. if we dont provide return type of main or any
}; other function, for example,
int main()
{ g(){} // implicitly means int g(){}
sort(vs.begin(), vs.end(), // generic algorithm However, implicit int was not supported for declaring of data in
[] (Shape* p, Shape* q) any place within the program, not even while passing arguments.
{ return p->box().first.x <q->box().first.x; } But, now we have auto in C++0x, lets explore.
);
Debasish Jana: C++ 0x is supporting a feature of determining the type
for (Shape* p: vs)
of a data automatically from the initializer or usage. For example,
delete p;
} auto x = 5;
will automatically determine that x is of type int, from its initializer.
How would I know (without likelihood of
What is the advantage of this feature? Is it because of the fact the
mistake) what is a suitable type to hold the sum
type is either difficult to write in specifically or it is a mean to support
of elements from U and V? With auto, I don’t generic programming in a better way?
have to know because the compiler already Bjarne Stroustrup: The key strength of auto is that it allows you to
does. avoid redundancy. Consider
Here, I’m showing off a few C++11 features. Note the initialization int x = 5;
of the vector of Shape pointers, the range-for loop, and the lambda Here we say that x is an int and that we initialize it with the int with
CSI Communications | August 2011 | 26 www.csi-india.org
CSIC August 2011.indd 26 8/6/2011 12:45:47 PM
6. the value 5. Here, that’s only a minor convenience, but consider: only just finished the C++11 standard. I have not had time for calm
thought about future long-term needs, so I can only mention some
void f(map<string,pair<int,int>>& m)
preliminary personal thoughts. I think we should look serious at a
{
simpler-to-use and simpler-to-implement concept design as the
for (map<string,pair<int,int>>::iterator p =
premier way of improving our support for generic programming.
m.begin(); p!=m.end(); ++p)
In general, we should focus language improvements on support
// ...
for abstraction (rather than directly supporting specific end-user
}
needs). I think we should look at multi-methods (e.g. see Peter
This is pretty ugly compared to Pirkelbauer, Yuriy Solodkyy, and Bjarne Stroustrup: “Open Multi-
void f(map<string,pair<int,int>>& m) Methods for C++” , Ref. URL: http://www.research.att.com/~bs/
{ multimethods.pdf, Proc. ACM GPCE’07) and I think we should
for (auto p = m.begin(); p!=m.end(); ++p) look into what would be needed to support multiple address
// ... spaces.
} The change should be fundamental rather than
The compiler knows the type of m, so we don’t need to tell it again serving a current fashion.
(and possibly get it wrong). The compiler also knows the value_
type of the map, so we could even write: For libraries, I’d like to revisit the various ideas about distributed
void f(map<string,pair<int,int>>& m) computing and in general look for ways to provide standard-
library support for higher-level concurrency models. I’d also like
{
to see some better support for linear algebra, but that may be
for (auto& x: m) selfish and frivolous. The pressure for change should come from
// ... the community rather than from within the standard committee.
} The change should be fundamental rather than serving a current
fashion. Only a library that has been designed, implemented, and
The pressure for change should come from the used by a community has a chance of becoming a standard library
community rather than from within the standard component.
committee. I think it will be important to look for major improvements rather
than more small “convenience features” and focus on library
And these are examples where we actually know the type. In more design.
complicated generic code, knowing the type isn’t always easy.
On Final Good wishes for the fan club, the learners, the
Consider a somewhat simplified example:
educators, the practitioners of C++ the community at
template<class U, class V> large
void f(U& u, V& v) Debasish Jana: I have been learning and preaching C++ for more
{ than two decades now and I don’t have any doubt whatsoever about
for(int i=0; i<u.size(); ++i) { the fact that C++ is the most brilliant language ever made. I am
auto tmp = u[i]+v[i]; personally delighted to know the C++0x taking its final shape and
// … being released in this year as part of the compiler supports.
} On behalf of C++ community at large, and from my personal admirer
} viewpoint, sincerest very special thanks to you, Prof. Stroustrup, for
spending so much time for showing us the way through this exclusive
How would I know (without likelihood of mistake) what is a interview, giving a chance to hold the torch of the glory and success
suitable type to hold the sum of elements from U and V? With of C++ in making more and more robust, resilient and adaptable
auto, I don’t have to know because the compiler already does. softwares.
Please remember that sometimes redundancy is a good thing: it Bjarne Stroustrup: Thanks, Debasish, for giving me an opportunity
helps catching errors. Therefore I recommend the use of auto only to explain about C++11. I’m looking forward to many new and even
in restricted scopes. I hope and expect that auto will be relatively more exciting applications.
rare for namespace variables. If a function gets so long that auto
becomes a source of confusion, the proper response will usually Only a library that has been designed,
be to shorten the function.
implemented, and used by a community has
On Wishlist a chance of becoming a standard library
Debasish Jana: Finally, your C++ wishlist, please.
Bjarne Stroustrup: Quality C++0x implementations. People component.
learning to use C++0x idiomatically. Better static analysis tools to
The entire series of all three parts of the exclusive interview with
cope with high-end applications.
Prof. Bjarne Stroustup is also listed under Interviews link at his
Oh, you meant new language features and library components! We home page: http://www2.research.att.com/~bs/ n
CSI Communications | August 2011 | 27
CSIC August 2011.indd 27 8/6/2011 12:45:47 PM