Best c++ questions in September 2011

Is this an g++ optimization bug?

58 votes

Below code works on Visual Studio 2008 with and without optimization. But it only works on g++ without optimization (O0).

#include <cstdlib>
#include <iostream>
#include <cmath>

double round(double v, double digit)
{
 double pow = std::pow(10.0, digit);
 double t = v * pow;
 //std::cout << "t:" << t << std::endl;
 double r = std::floor(t + 0.5);
 //std::cout << "r:" << r << std::endl;
 return r / pow;
}

int main(int argc, char *argv[])
{
 std::cout << round(4.45, 1) << std::endl;
 std::cout << round(4.55, 1) << std::endl;
}

Output should be: 4.5 4.6

But g++ with optimization (O1 - O3) will output 4.5 4.5

if I add volatile keyword before t, it works, so I think there might be some kind of optimization bug?

Test on g++ 4.1.2, and 4.4.4.

Edit:

Here is the result on ideone: http://ideone.com/Rz937

And the option I test on g++ is simple: g++ -O2 round.cpp

Edit2:

The more interesting result, even I turn on /fp:fast option on Visual Studio 2008, the result still is correct.

Further question:

I was wondering, should I always turn on -ffloat-store option?

Because the g++ version I tested is shipped with CentOS/Redhat 5 and CentOS/Redhat 6.

I compiled many my programs under these platforms, I am worry about that will cause unexpected bugs inside my programs. It seems a little difficult to investigate all my C++ code and used libraries whether have such problem. Any suggestion?

Edit3:

Is anyone interested in why even /fp:fast turned on, Visual Studio 2008 still works? It seems like VS2008 is more reliable at this problem than g++?

Intel x86 processors use 80-bit extended precision internally, whereas double is normally 64-bit wide. Different optimization levels affect how often floating point values from CPU get saved into memory and thus rounded from 80-bit precision to 64-bit precision.

Use the -ffloat-store gcc option to get the same floating point results with different optimization levels.

Alternatively, use the long double type, which is normally 80-bit wide on gcc to avoid rounding from 80-bit to 64-bit precision.

man gcc says it all:

   -ffloat-store
       Do not store floating point variables in registers, and inhibit
       other options that might change whether a floating point value is
       taken from a register or memory.

       This option prevents undesirable excess precision on machines such
       as the 68000 where the floating registers (of the 68881) keep more
       precision than a "double" is supposed to have.  Similarly for the
       x86 architecture.  For most programs, the excess precision does
       only good, but a few programs rely on the precise definition of
       IEEE floating point.  Use -ffloat-store for such programs, after
       modifying them to store all pertinent intermediate computations
       into variables.

Unusual typedef use in C++

45 votes

I came across a new use of the keyword typedef in C++.

What does this typedef statement mean ?

int typedef foo;

It's the same as

typedef int foo;

i.e. it defines foo to be the type int. While the grammar allows to swap typedef and int in this case, you usually would not do this because it impairs readability.

Is string::c_str() no longer null terminated in C++11?

43 votes

In C++11 basic_string::c_str is defined to be exactly the same as basic_string::data, which is in turn defined to be exactly the same as *(begin() + n) and *(&*begin() + n) (when 0 <= n < size()).

I cannot find anything that requires the string to always have a null character at its end.

Does this mean that c_str() is no longer guaranteed to produce a null-terminated string?

Strings are now required to use null-terminated buffers internally. Look at the definition of operator[] (21.4.5):

Requires: pos <= size().

Returns: *(begin() + pos) if pos < size(), otherwise a reference to an object of type T with value charT(); the referenced value shall not be modified.

Looking back at c_str (21.4.7.1), we see that it is defined in terms of operator[]:

Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].

And both c_str and data are required to be O(1), so the implementation is effectively forced to use null-terminated buffers.

Additionally, as David Rodríguez - dribeas points out in the comments, the return value requirement also means that you can use &operator[](0) as a synonym for c_str(), so the terminating null character must lie in the same buffer (since *(p + size()) must be equal to charT()); this also means that if the terminator is initialised lazily, it's not possible to observe the buffer in the intermediate state.

Why does a C comment like /* */ need '<'?

41 votes

My teams C-code guidelines write that it'd be better to place a '<' in a comment like shown below:

#define MAX_PACK_ITEM_NUM 50  /**<  max number of item */

I wonder, what is the real use of this '<' ?

It's a way for doxygen to generate documentation for members of a file/struct/union/class/enum. By using that marker, you can put comments after each member, leading to less clutter. You can read more about it here.

Does dynamic memory allocation differ in C and C++ in popular implementations?

39 votes

As far as the respective language standards go, C offers dynamic memory allocation only through the malloc() family, while in C++ the most common form of allocation is performed by ::operator new(). The C-style malloc is also available in C++, and many "baby's first allocator" examples use it as its core allocation function, but I am curious how contemporary compilers implement the actual production operator-new.

Is it just a thin wrapper around malloc(), or is it implemented fundamentally differently on account of the rather different memory allocation behaviour of a typical C++ program compared to a typical C program?

[Edit: I believe the main difference is usually described as follows: A C program has fewer, larger, long-lived allocations, while a C++ program has many, small, short-lived allocations. Feel free to chime in if that's mistaken, but it sounds like one would benefit from taking this into account.]

For a compiler like GCC it would be easy to just have one single core allocation implementation and use that for all relevant languages, so I wonder if there are differences in the details that try to optimize the resulting allocation performance in each language.


Update: Thanks for all the great answers! It looks like in GCC this is completely solved by ptmalloc, and that MSVC also uses malloc at the core. Does anyone know how the MSVC-malloc is implemented?

Here is the implementation used by g++ 4.6.1:

_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) throw (std::bad_alloc)
{
  void *p;

  /* malloc (0) is unpredictable; avoid it.  */
  if (sz == 0)
    sz = 1;
  p = (void *) malloc (sz);
  while (p == 0)
    {
      new_handler handler = __new_handler;
      if (! handler)
#ifdef __EXCEPTIONS
        throw bad_alloc();
#else
        std::abort();
#endif
      handler ();
      p = (void *) malloc (sz);
    }

  return p;
}

This is found in libstdc++-v3/libsupc++/new_op.cc inside the g++ source distro.

As you can see, it's a fairly thin wrapper around malloc.

edit On many systems it is possible to fine-tune the behaviour of malloc, typically by calling mallopt or setting environment variables. Here is one article discussing some features available on Linux.

According to Wikipedia, glibc versions 2.3+ use a modified version of the allocator called ptmalloc, which itself is a derivative of dlmalloc designed by Doug Lea. Interestingly, in an article about dlmalloc Doug Lea gives the following perspective (emphasis mine):

I wrote the first version of the allocator after writing some C++ programs that almost exclusively relied on allocating dynamic memory. I found that they ran much more slowly and/or with much more total memory consumption than I expected them to. This was due to characteristics of the memory allocators on the systems I was running on (mainly the then-current versions of SunOs and BSD ). To counter this, at first I wrote a number of special-purpose allocators in C++, normally by overloading operator new for various classes. Some of these are described in a paper on C++ allocation techniques that was adapted into the 1989 C++ Report article Some storage allocation techniques for container classes.

However, I soon realized that building a special allocator for each new class that tended to be dynamically allocated and heavily used was not a good strategy when building kinds of general-purpose programming support classes I was writing at the time. (From 1986 to 1991, I was the the primary author of libg++ , the GNU C++ library.) A broader solution was needed -- to write an allocator that was good enough under normal C++ and C loads so that programmers would not be tempted to write special-purpose allocators except under very special conditions.

This article presents a description of some of the main design goals, algorithms, and implementation considerations for this allocator.

Metaprogramming in C++ and in D

38 votes

The template mechanism in C++ only accidentally became useful for template metaprogramming. On the other hand, D's was designed specifically to facilitate this. And apparently it's even easier to understand (or so I've heard).

I've no experience with D, but I'm curious, what is it that you can do in D and you cannot in C++, when it comes to template metaprogramming?

The two biggest things that help template metaprogramming in D are template constraints and static if - both of which C++ could theoretically add and which would benefit it greatly.

Template constraints allow you to put a condition on a template that must be true for the template to be able to be instantiated. For instance, this is the signature of one of std.algorithm.find's overloads:

R find(alias pred = "a == b", R, E)(R haystack, E needle)
    if (isInputRange!R &&
        is(typeof(binaryFun!pred(haystack.front, needle)) : bool))

In order for this templated function to be able to be instantiated, the type R must be an input range as defined by std.range.isInputRange (so isInputRange!R must be true), and the given predicate needs to be a binary function which compiles with the given arguments and returns a type which is implicitly convertible to bool. If the result of the condition in the template constraint is false, then the template won't compile. Not only does this protect you from the nasty template errors that you get in C++ when templates won't compile with their given arguments, but it makes it so that you can overload templates based on their template constraints. For instance, there's another overload of find which is

R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2
        && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)
        && !isRandomAccessRange!R1)

It takes exactly the same arguments, but its constraint is different. So, different types work with different overloads of the same templated function, and the best implementation of find can be used for each type. There's no way to do that sort of thing cleanly in C++. With a bit of familiarity with the functions and templates used in your typical template constraint, template constraints in D are fairly easy to read, whereas you need some very complicated template metaprogramming in C++ to even attempt something like this, which your average programmer is not going to be able to understand, let alone actually do on their own. Boost is a prime example of this. It does some amazing stuff, but it's incredibly complicated.

static if improves the situation even further. Just like with template constraints, any condition which can be evaluated at compile time can be used with it. e.g.

static if(isIntegral!T)
{
    //...
}
else static if(isFloatingPoint!T)
{
    //...
}
else static if(isSomeString!T)
{
    //...
}
else static if(isDynamicArray!T)
{
    //...
}
else
{
    //...
}

Which branch is compiled in depends on which condition first evaluates to true. So, within a template, you can specialize pieces of its implementation based on the types that the template was instantiated with - or based on anything else which can be evaluated at compile time. For instance, core.time uses

static if(is(typeof(clock_gettime)))

to compile code differently based on whether the system provides clock_gettime or not (if clock_gettime is there, it uses it, otherwise it uses gettimeofday).

Probably the most stark example that I've seen where D improves on templates is with a problem which my team at work ran into in C++. We needed to instantiate a template differently based on whether the type it was given was derived from a particular base class or not. We ended up using a solution based on this stack overflow question. It works, but it's fairly complicated for just testing whether one type is derived from another.

In D, however, all you have to do is use the : operator. e.g.

auto func(T : U)(T val) {...}

If T is implicitly convertible to U (as it would be if T were derived from U), then func will compile, whereas if T isn't implicitly convertible to U, then it won't. That simple improvement makes even basic template specializations much more powerful (even without template constraints or static if).

Personally, I rarely use templates in C++ other than with containers and the occasional function in <algorithm>, because they're so much of a pain to use. They result in ugly errors and are very hard to do anything fancy with. To do anything even a little bit complicated, you need to be very skilled with templates and template metaprogramming. With templates in D though, it's so easy that I use them all the time. The errors are much easier to understand and deal with (though they're still worse than errors typically are with non-templated functions), and I don't have to figure out how to force the language into doing what I want with fancy metaprogramming.

There's no reason that C++ couldn't gain much of these abilities that D has (C++ concepts would help if they ever get those sorted out), but until they add basic conditional compilation with constructs similar to template constraints and static if to C++, C++ templates just won't be able to compare with D templates in terms of ease of use and power.

33 votes

I've recently seen two really nice and educating languages talks:

This first one by Herb Sutter, presents all the nice and cool features of C++0x, why C++'s future seems brighter than ever, and how M$ is said to be a good guy in this game. The talk revolves around efficiency and how minimizing heap activity very often improves performance.

This other one, by Andrei Alexandrescu, motivates a transition from C/C++ to his new game-changer D. Most of D's stuff seems really well motivated and designed. One thing, however, surprised me, namely that D pushes for garbage collection and that all classes are created solely by reference. Even more confusing, the book The D Programming Language Ref Manual specifically in the section about Resource Management states the following, quote:

Garbage collection eliminates the tedious, error prone memory allocation tracking code necessary in C and C++. This not only means much faster development time and lower maintenance costs, but the resulting program frequently runs faster!

This conflicts with Sutter's constant talk about minimizing heap activity. I strongly respect both Sutter's and Alexandrescou's insights, so I feel a bit confused about these two key questions

  1. Doesn't creating class instances solely by reference result in a lot of unnecesseary heap activity?

  2. In which cases can we use Garbage Collection without sacrificing run-time performance?

To directly answer your two questions:

  1. Yes, creating class instances by reference does result in a lot of heap activity, but:

    a. In D, you have struct as well as class. A struct has value semantics and can do everything a class can, except polymorphism.

    b. Polymorphism and value semantics have never worked well together due to the slicing problem.

    c. In D, if you really need to allocate a class instance on the stack in some performance-critical code and don't care about the loss of safety, you can do so without unreasonable hassle via the scoped function.

  2. GC can be comparable to or faster than manual memory management if:

    a. You still allocate on the stack where possible (as you typically do in D) instead of relying on the heap for everything (as you often do in other GC'd languages).

    b. You have a top-of-the-line garbage collector (D's current GC implementation is admittedly somewhat naive, though it has seen some major optimizations in the past few releases, so it's not as bad as it was).

    c. You're allocating mostly small objects. If you allocate mostly large arrays and performance ends up being a problem, you may want to switch a few of these to the C heap (you have access to C's malloc and free in D) or, if it has a scoped lifetime, some other allocator like RegionAllocator. (RegionAllocator is currently being discussed and refined for eventual inclusion in D's standard library).

    d. You don't care that much about space efficiency. If you make the GC run too frequently to keep the memory footprint ultra-low, performance will suffer.

Why can't we have automatically deduced return types?

30 votes

Recently I was working a friend who wanted to make C++ more Haskell-y, and we wanted a function that's basically like this:

auto sum(auto a, auto b) {
    return a + b;
}

Apparently I can't use auto as a parameter type, so I changed it to this:

template<class A, class B>
auto sum(A a, B b) {
    return a + b;
}

But that doesn't work either. What we eventually realized we need this:

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b) {
    return a + b;
}

So my question is, what's the point? Isn't decltype just repeating information, since the compiler can just look at the return statement?

I considered that maybe it's needed so we can just include a header file:

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);

... but we can't use templates like that anyway.

The other thing I considered was that it might be easier for the compiler, but it seems like it would actually be harder.

Case 1: With decltype

  • Figure out the type of the decltype statement
  • Figure out the types of any return values
  • See if they match

Case 2: Without decltype

  • Figure out the types of any return values
  • See if they match

So with those things in mind, what's the point of the trailing return type with decltype?

What if we have the following:

template<class A, class B, class C>
auto sum(A a, B b, C c) {
   if (rand () == 0) return a + b;

   // do something else...

    return a + c;
}

.. where a + b and a + c expressions yield different type of results. What should compiler decide to put as a return type for that function and why? This case is already covered by C++11 lambdas which allow to omit the return type as long as return statements can be deduced to the same type (NB standard quote needed, some sources claim only one return expression is allowed and that this is a gcc glitch).


A technical reason is that C++ allows the definition and declaration to be separate.

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b)
{
}

The definition of the template could be in the header. Or it could be in another file, so that you don't have to wade through pages and pages of function definitions when looking through an interface.

C++ has to account for all possibilities. Restricting trailing return types to just function definitions means that you can't do something as simple as this:

template<class A, class B>
class Foo
{
  auto sum(A a, B b) -> decltype(a + b);
}

template<class A, class B>
auto Foo<A, B>::sum(A a, B b) -> decltype(a + b)
{
}

Will using `goto` leak variables?

24 votes

Is it true that goto jumps across bits of code without calling destructors and things?

e.g.

void f() {
   int x = 0;
   goto lol;
}

int main() {
   f();
lol:
   return 0;
}

Won't x be leaked?

Warning: This answer pertains to C++ only; the rules are quite different in C.


Won't x be leaked?

No, absolutely not.

It is a myth that goto is some low-level construct that allows you to override C++'s built-in scoping mechanisms. (If anything, it's longjmp that may be prone to this.)

Consider the following mechanics that prevent you from doing "bad things" with labels (which includes case labels).


1. Label scope

You can't jump across functions:

void f() {
   int x = 0;
   goto lol;
}

int main() {
   f();
lol:
   return 0;
}

// error: label 'lol' used but not defined

[n3290: 6.1/1]: [..] The scope of a label is the function in which it appears. [..]


2. Object initialisation

You can't jump across object initialisation:

int main() {
   goto lol;
   int x = 0;
lol:
   return 0;
}

// error: jump to label ‘lol’
// error:   from here
// error:   crosses initialization of ‘int x’

If you jump back across object initialisation, then the object's previous "instance" is destroyed:

struct T {
   T() { cout << "*T"; }
  ~T() { cout << "~T"; }
};

int main() {
   int x = 0;

  lol:
   T t;
   if (x++ < 5)
     goto lol;
}

// Output: *T~T*T~T*T~T*T~T*T~T*T~T

[n3290: 6.6/2]: [..] Transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction of objects with automatic storage duration that are in scope at the point transferred from but not at the point transferred to. [..]

You can't jump into the scope of an object, even if it's not explicitly initialised:

int main() {
   goto lol;
   {
      std::string x;
lol:
      x = "";
   }
}

// error: jump to label ‘lol’
// error:   from here
// error:   crosses initialization of ‘std::string x’

... except for certain kinds of object, which the language can handle regardless because they do not require "complex" construction:

int main() {
   goto lol;
   {
      int x;
lol:
      x = 0;
   }
}

// OK

[n3290: 6.7/3]: It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer. [..]


3. Jumping abides by scope of other objects

Likewise, objects with automatic storage duration are not "leaked" when you goto out of their scope:

struct T {
   T() { cout << "*T"; }
  ~T() { cout << "~T"; }
};

int main() {
   {
      T t;
      goto lol;
   }

lol:
   return 0;
}

// *T~T

[n3290: 6.6/2]: On exit from a scope (however accomplished), objects with automatic storage duration (3.7.3) that have been constructed in that scope are destroyed in the reverse order of their construction. [..]


Conclusion

The above mechanisms ensure that goto doesn't let you break the language.

Of course, this doesn't automatically mean that you "should" use goto for any given problem, but it does mean that it is not nearly as "evil" as the common myth leads people to believe.

Can I use template aliases as template template parameters?

22 votes

Can I use template aliases as template template parameters?

template <template <typename> class> struct foo {};

template <typename T> using simple_ptr = std::unique_ptr<T>;

foo<std::unique_ptr> a; // this doesn't work, std::unique_ptr has two parameters
foo<simple_ptr> b; // does this work?

Yes, it is apparently allowed. According to the latest draft of the upcoming standard I could find, it is stated that

A template-argument for a template template-parameter shall be the name of a class template or an alias template [...].

However, alias templates seems very seldomly supported at the moment, so you might have some trouble making it work with most compilers.

What does the operation c=a+++b mean?

22 votes

Possible Duplicate:
How is the expression x---y parsed? Is it a legal expression?

The following code has me confused

int a=2,b=5,c;
c=a+++b;
printf("%d,%d,%d",a,b,c);

I expected the output to be 3,5,8, mainly because a++ means 2 +1 which equals 3, and 3 + 5 equals 8, so I expected 3,5,8. It turns out that the result is 3,5,7. Can someone explain why this is the case?

It's parsed as c = a++ + b, and a++ means post-increment, i.e. increment after taking the value of a to compute a + b == 2 + 5.

Please, never write code like this.

Why is ~size_t(0) (== 0xFFFFFFFF in most 32-bit systems) not a valid array index?

19 votes

Quoting from this blogpost:

http://www.codesynthesis.com/~boris/blog/2008/10/13/writing-64-bit-safe-code/

This works because a valid memory index can only be in the [0, ~size_t(0)-1] range. The same approach, for example, is used in std::string.

So why is ~size_t(0) (this should usually equal 0xFFFFFFFF in 32-bit systems) not a valid array index? I assume that if you have 32 bits you should be able to reference the whole range [0, 0xFFFFFFFF], no?

IMPORTANT NOTE: The term "memory index" is ambiguous and confusing. The linked article refers strictly to array indexes, not addresses in memory. It is entirely valid for size_t to be incapable of representing all memory addresses, which is why we have the intptr_t type in C99. Of course, this doesn't apply to your workstation, which undoubtedly has a simple Von Neumann type architecture. (The question has since been edited to remove references to "memory indexes".)

The C standard guarantees that size_t can hold the size of any array. However, for any array a[N], the standard guarantees that a + N must be a valid pointer and compare not equal to any pointer to an element of a.

Therefore, size_t must be able to represent at least one value larger than any possible array index. Since ~(size_t)0 is guaranteed to be the maximum size_t value, it is a good choice of sentinel for array indexes.

Discussion:

  1. Why is ~(size_t)0 guaranteed to be the maximum? Because the standard explicitly says so: from §6.5.3.3: "If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E." Note that (size_t)-1 is guaranteed to also be the maximum by the rules of conversion from signed to unsigned types. Unfortunately, it is not always easy to find the definition for SIZE_MAX on your platform, so (size_t)-1 and ~(size_t)0 are preferred.

  2. What is the size of an array indexed from 0 to ~0? Such an array cannot exist according to the C standard, by the argument outlined at the top of this post.

  3. If you malloc(-1), the resulting memory region would have to start at 0. (FALSE) There are a lot of really bizarre cases which the standard allows but one doesn't encounter in practice. For example, imagine a system where (uintptr_t)-1 > (size_t)-1. The C standard is worded in exactly the way it is because it doesn't just run on your PC, it runs on bizarre little DSPs with Harvard architectures, and it runs on archaic systems with byzantine memory segmenting schemes. There are also some systems of historical interest where NULL pointers do not have the same representation as 0.

C++ Templates: Angle brackets problems

19 votes

In C++ templates are instantiated with angle brackets vector<int> and the Java and C# languages have adopted the same syntax for their generics.

The creators of D, however, have been quite vocal about the problems that angle brackets bring and they made a new syntax foo!(int) — but I've never seen too many details about what problems angle brackets bring, exactly.

One of them was when instantiating a template with another template vector<vector<int>>, which would cause some (older?) compilers to confuse the trailing '>>` with the bit-shift or streaming operators. The solution was to insert a space between the two angle brackets, but haven't compilers become able to parse that syntax, nowadays?

Another problem was when using the greater-than operator foo<3 > 2>. The parser would think that the operator actually closes the template instantiation; the fix was to introduce parentheses foo<(3 > 2)>. But I don't think there that many cases where you need to do this and, at any rate, I'd rather have to type the extra parentheses when they are needed, instead of introducing new syntax and always having to type the exclamation mark.

What other problems are there with angle brackets that made the D developers create a new syntax?

but haven't compilers become able to parse that syntax, nowadays?

Of course. But it’s far from trivial. In particular, it prevents you from implementing a clean separation between context-unaware lexer and parser. This is particularly irksome for syntax highlighters and other support tools that need to parse C++, but don’t want/can implement a fully-fledged syntactical analyser.

It makes C++ so much harder to parse that a lot of tools simply won’t bother. This is a net loss for the ecosystem. Put differently: it makes developing a parsing tool much more expensive.

For instance, ctags fails for some template definitions, which makes it unusable with our current C++ project. Very annoying.

But I don't think there that many cases where you need to [distinguish between angle brackets and less-than]

It doesn’t matter how often you need to do this. Your parser still needs to handle this.

D’s decision to drop angle backets was a no-brainer. Any one reason would have sufficed, given that it’s a net benefit.

Why can't a constant pointer be a constant expression?

19 votes

The following program compiles:

template <const int * P>
class Test{};

extern const int var = 42; //extern needed to force external linkage

int main()
{
    Test<&var> test;
}

This one, however, doesn't, which is a surprise for me:

template <const int * P>
class Test{};

extern const int var = 42; //extern needed to force external linkage
extern const int * const ptr = &var; //extern needed to force external linkage
int main()
{
    Test<ptr> test; //FAIL! Expected constant expression.
}

Alternative example:

int main()
{
   const int size = 42;
   int ok[*&size]; //OK

   const int * const pSize = &size;
   int fail[*pSize]; //FAIL
}

I have concluded that a pointer just can't be a constant expression regardless of whether it's const and initialized with a constant expression.

Questions:

  1. Is my conclusion true?
  2. If so, why can't a pointer be a constant expression? If not, why don't the above programs compile?
  3. Does C++0x(C++11, if you will) change anything?

Thanks for any insights!

It's a bit more complicated. In C++03 and C++11, &var is a constant expression if var is a local static / class static or namespace scope variable. This is called an address constant expression. Initializing a class static or namespace scope pointer variable with that constant expression is guaranteed to be done before any code is run (static initialization phase), because of it being a constant expression.

However only in C++11, a constexpr pointer variable that stores the address &var can also be used as an address constant expression and only in C++11, you can dereference an address constant expression (actually, you can dereference even more - even local array element addresses, but let's keep it ontopic) and if it refers to a constant integral variable initialized prior to the dereference or a constexpr variable, you again get a constant expression (depending on the type and value category, the kind of constant expression may vary). As such, the following is valid C++11:

int const x = 42;
constexpr int const *px = &x;

// both the value of "px" and the value of "*px" are prvalue constant expressions
int array[*px];
int main() { return sizeof(array); }

If so, why can't a pointer be a constant expression? If not, why don't the above programs compile?

This is a known limitation in the Standard's wording - it currently only allows other template parameters as arguments or & object, for a template parameter of pointer type. Even though the compiler should be capable of doing much more.

In C++11, what is the point of a thread which "does not represent a thread of execution"?

19 votes

Looking over the new threading stuff in C++11 to see how easily it maps to pthreads, I notice the curious section in the thread constructor area:

thread();
Effects: Constructs a thread object that does not represent a thread of execution.
Postcondition: get_id() == id()
Throws: Nothing.

In other words, the default constructor for a thread doesn't actually seem to create a thread. Obviously, it creates a thread object, but how exactly is that useful if there's no backing code for it? Is there some other way that a "thread of execution" can be attached to that object, like thrd.start() or something similar?

Is there some other way that a "thread of execution" can be attached to that object, like thrd.start() or something similar?

// deferred start
std::thread thread;

// ...

// let's start now
thread = std::thread(functor, arg0, arg1);

std::thread is a MoveConstructible and MoveAssignable type. So that means that in code like std::thread zombie(some_functor); std::thread steal(std::move(zombie)); zombie will be left in a special, but valid, state associated with no thread of execution. The default constructor comes free in a sense since all it has to do is put the object into that exact state. It also allows arrays of std::thread and operations like std::vector<std::thread>::resize.

To "if, if, if" or to "if, else if, else if, else"

18 votes

I am writing some code for data analysis, and have to exclude samples based on some criteria. In practice I end up writing code such as:

bool Test(SampleType sample)
{
  if( ! SubTest1(sample) )
    return false;
  if( ! SubTest2(sample) )
    return false;
  if( ! SubTest3(sample) )
    return false;

  return true;
}

The following seems equivalent to me:

bool Test(SampleType sample)
{
  if( ! SubTest1(sample) )
    return false;
  else if( ! SubTest2(sample) )
    return false;
  else if( ! SubTest3(sample) )
    return false;
  else 
    return true;
}

Is there a difference in terms of computing cost? Is there a arguable preferential one in terms of extendibility/maintainability, aesthetics, etc...?

I know this is probably an inconsequential issue, but once I get these questions stuck in my head I NEED to find the answer.

PS: in case anyone cares, my actual code as of 15/09 can be found at the following: http://folk.uio.no/henrikq/conf.tgz

Compiler generates the same code for both the versions. But the 1st version is better in maintainability aspect if you compare just with the 2nd version.

The code exits when the return statement is encountered; so there is no use of keeping else in the upcoming if. It makes the developer understand the code better.

Also, if this is the literal code then you can still shrink as,

bool Test(SampleType sample)
{
  return (SubTest1(sample) && SubTest2(sample) && SubTest3(sample));
}

Why can't I create a vector of lambda in C++11?

18 votes

I was trying to create a vector of lambda, but failed:

auto ignore = [&]() { return 10; };  //1
std::vector<decltype(ignore)> v;     //2
v.push_back([&]() { return 100; });  //3

Up to line #2, it compiles fine. But the line#3 gives compilation error:

error: no matching function for call to 'std::vector<main()::<lambda()>>::push_back(main()::<lambda()>)'

I don't want a vector of function pointers or vector of function objects. However, vector of function objects which encapsulate real lambda expressions, would work for me. Is this possible?

Every lambda has a different type- even if they have the same signature. You must use a run-time encapsulating container such as std::function if you want to do something like that.

e.g.:

std::vector<std::function<int()>> functors;
functors.push_back([&] { return 100; });
functors.push_back([&] { return 10; });

I don't want a vector of function pointers or vector of function objects.

Well, I would like a nice high-paying job with a hundred-man developer team to develop all my dreams, but that's not gonna happen either. Oh, and I'd also like a very attractive wife who can cook and clean, since I really can't.

Efficient way to convert a 16-bit short array to a 32-bit int array?

16 votes

What is the most efficient way to convert an array of unsigned short numbers (16 bits per value) into an array of unsigned ints numbers (32 bits per value)?

Copy it.

unsigned short source[]; // …
unsigned int target[]; // …
unsigned short* const end = source + sizeof source / sizeof source[0];
std::copy(source, end, target);

std::copy internally choses the best copying mechanism for given input types. In this case, however, there’s probably no better way than copying the elements individually in a loop.

What exactly is a type cast in C/C++?

15 votes

What exactly is a type cast in C/C++? How does the compiler check if an explicit typecast is needed (and valid)? Does it compare the space required for an value? If I have for example:

int a;
double b = 15.0;
a = (int) b;

If I remember correctly a double value requires more space (was it 8 bytes?!) than an integer (4 bytes). And the internal represantation of both are completely different (complement on two/mantissa). So what happens internally? The example here is quite straightforward, but in C/C++ there are plentiful typecasts. How does the compiler know (or the programmer if I can cast e.g. FOO to BAR)?

A type cast is basically a conversion from one type to another. It can be implicit (i.e., done automatically by the compiler, perhaps losing info in the process) or explicit (i.e., specified by the developer in the code). The space occupied by the types is of secondary importance. More important is the applicability (and sometimes convenice) of conversion.

It is possible for implicit conversions to lose information, signs can be lost / gained, and overflow / underflow can occur. The compiler will not protect you from these events, except maybe through a warning that is generated at compile time. Slicing can also occur when a derived type is implicitly converted to a base type (by value).

For conversions that can be downright dangerous (e.g., from a base to a derived type), the C++ standard requires an explicit cast. Not only that, but it offers more restrictive explicit casts, such as static_cast, dynamic_cast, reinterpret_cast, and const_cast, each of which further restricts the explicit cast to only a subset of possible conversions, reducing the potential for casting errors.

Valid conversions, both implicit and explict are ultimately defined by the C/C++ standards, although in C++, the developer has the ability to extend conversions for user defined types, both implicit and explicit, via the use of constructors and overloaded (cast) operators.

The complete rules for which casts are allowed by the standards and which are not can get quite intricate. I have tried to faithfully present a somewhat concise summary of some of those rules in this answer. If you are truly interested in what is and is not allowed, I strongly urge you to visit the standards and read the respective sections on type conversion.

Difference between exception handling in C++ and Java?

14 votes

In Java, if a specific line of code causes the program to crash, then the exception is caught and the program continues to execute.

However, in C++, if I have a piece of code that causes the program to crash, like:

try
{
        int x = 6;
        int *p = NULL;
        p = reinterpret_cast<int*>(x);

        *p = 10; // the program crashed here

        cout << "x = " << *p << endl;
    }
    catch(const char* Message)
    {
        cout << "There is an run-time error";
    }

Then the program still crash and the exception is not caught.

So what is the point of exception handling in C++? Am I misunderstanding something?

The line that crashes is dereferencing an invalid pointer. In C++ this will not throw an exception. Instead it is undefined behaviour.

There's no such thing as a null pointer exception in C++, unlike Java which will throw a null pointer exception. Instead dereferencing an invalid pointer will lead to undefined behaviour. Undefined behaviour does not always imply a crash, however if it crashes you're lucky.

Language overview:

Finally and RAII

One of the most significant differences bewtween C++ and Java is that Java supports a finally statement. Code in the finally block is always run regardless of whether code in the preceding catch block is executed or not. For example:

try
{
}
catch (SomeException e)
{
}
finally
{
  //code here is always exectued.
}

The purpose of the finally statement is to allow the programmer cleanup at that point, i.e. release sockets, close file handles etc... Even though Java runs a garbage collector, garbage collection only applies to memory and no other resource. There are still occasions where you have to manually dispose of resources. Now C++ doesn't have a finally statement so users of the language are advised to adhere to the RAII principle (Resouce Acquisition is Initialization) Stroustrup has an explanation about it here: http://www2.research.att.com/~bs/bs_faq2.html#finally. I prefer to call it Resource destruction is deallocation but basically when your object falls out of scope, invoking the destructor, then that destructor should release whatever resources the object maintained.

For example, C++11x provides a std::unique_ptr to manage this:

void foo()
{
  std::unique_ptr<T> t(new T)
  try
  {
    //code that uses t
  }
  catch (...)
  {
  }
}

The resource allocated via new will be deleted when the function ends.

catch all statements

Because all exceptions in Java inherit from a common base class Exception if you want your catch clause to catch any exception, then set it up like this:

catch (Exception e)
{
  //any exception thrown will land here.
}

In C++ there's no restriction on what can be thrown and no common base class for all exceptions. Standard practice is to form your custom exception class by inheriting from std::exception but the language doesn't enforce this. Instead there's a special syntax for catching all exceptions:

catch (...)
{

}

Unhandled exceptions

This is another area where the languages behave differently. In C++ a thrown exception that is not caught will call std::terminate. std::terminate's default behaviour is to call abort which generates a SIGABRT and the entire program stops.

In Java the behaviour is to print a stack trace and terminate the thread that the uncaught exception occured in. However because a Java programmer may provide an UncaughtException handler, the behaviour could quite well be different from the default of terminating the thread.