Month: June 2016

Example of writing a class that implements c++11 range based for helpers

June 28, 2016 C/C++ development and debugging. No comments , ,

If a class provides begin and end functions returning iterator objects, and that iterator has a != operator, then the class can be used in a range based for. Here’s an example that allows for iterating over all the bits in an integer. For example, suppose that

0b10101010

is a representation of the set:

128, 32, 8, 2

or

1<<7, 1<<5, 1<<3, 1<<1

We can iterate over the set with a set of bit shifts, and use the following setup to do so

class bititer
{
   unsigned bset ;
   int cur{} ;
 
public:

   bititer( const unsigned b )
      : bset{ b }
   {
   }

   bititer & operator++()
   {
      bset >>= 1 ;
      cur++ ;

      return *this ;
   }

   unsigned operator*()
   {
      unsigned v{} ;

      if ( bset & 1 )
      {
         v = ( 1 << cur ) ;
      } 

      return v ;
   }

   bool operator !=( const bititer & b )
   {
      return ( bset != b.bset ) ;
   }
} ;

Iteration can now be done once a container adapter that provides the begin and end functions is implemented:

struct bitset
{
   unsigned bits ;

   bititer begin()
   {
      return bititer{ bits } ;
   }

   bititer end()
   {
      return bititer{ 0 } ;
   }
} ;

int main()
{
   for ( auto v : bitset{ 0b10101010 } )
   {
      std::cout << v << "\n" ;
   }

   return 0 ;
}

Note that the 0b10101010 syntax is from c++14, not c++11.

Stroustrup reading notes: delagating constructors, default, delete, move, literals

June 26, 2016 C/C++ development and debugging. No comments , , , , , , , ,

Here’s more notes from reading Stroustrup’s “The C++ Programming Language, 4th edition”

Alternate construction methods

I’d seen the new inline member initialization syntax that can be used to avoid (or simplify) explicit constructors. For example, instead of

struct physical
{
   double  c      ;  ///< wave speed
   double  tau    ;  ///< damping time
   double  x1     ;  ///< left most x value
   double  x2     ;  ///< right most x value

   /**
     set physical parameters to some defaults
    */
   physical() ;
} ;

physical::physical() :
   c{ 1.0 },
   tau{ 20.0 },
   x1{ -26.0 },
   x2{ +26.0 }
{
}

You can do

struct physical
{
   double c{ 1.0 }    ;  ///< wave speed
   double tau{ 20.0 } ;  ///< damping time
   double x1{ -26.0 } ;  ///< left most x value
   double x2{ +26.0 } ;  ///< right most x value
} ;

Much less code to write, and you can keep things all in one place. I wondered if this could be combined with constexpr, but the only way I could get that to work was to use static members, which also have to have an explicit definition (at least on Mac) to avoid a link error:

struct p2
{  
   static constexpr double x2{ +26.0 } ;  ///< right most x value
} ;
constexpr double p2::x2 ;

int main()
{  
   p2 p ;

   return p.x2 ;
}

But that is a digression. What I wanted to mention is that, while member initialization is cool, there’s more in the C++11 constructor simplification toolbox. We can write a constructor that builds on the member constructors (if any), but we can also make constructor specialations just call other constructors (called a delegating constructor), like so

struct physical
{
   double c{ 1.0 }    ;  ///< wave speed
   double tau{ 20.0 } ;  ///< damping time
   double x1{ -26.0 } ;  ///< left most x value
   double x2{ +26.0 } ;  ///< right most x value

   physical( const double cv ) : c{cv} {}
   physical( const double x1v, const double x2v ) : x1{x1v}, x2{x2v} {}

   physical( const double cv, const int m ) : physical{cv} { c *= m ; } ;
} ;

Stroustrup points out that the object is considered initialized by the time the delegating constructor is called. So if that throws, we shouldn’t get to the body of the constructor function

#include <iostream>

struct physical
{
   double c{ 1.0 }    ;  ///< wave speed

   physical( const double cv ) { throw 3 ; }

   physical( const double cv, const int m ) : physical{cv} { std::cout << "won't get here\n" ; }
} ;

int main()
try
{
   physical p{5} ;

   return 0 ;
}
catch (...)
{
   return 1 ;
}

default functions

If we define a structure with an explicit constructor with parameters, then unless explicit action is taken, this means that we no longer get a default constructor. Example:

#include <string>

struct F
{
   std::string s{} ;
   
   F( int n ) : s( n, 'a' ) {}
} ;

F x ;

This results in errors because the default constructor has been deleted by defining an explicit constructor

$ c++ -o d -std=c++11 d.cc
d.cc:10:3: error: no matching constructor for initialization of 'F'
F x ;
  ^
d.cc:7:4: note: candidate constructor not viable: requires single argument 'n', but no arguments were provided
   F( int n ) : s( n, 'a' ) {}
   ^
d.cc:3:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
struct F
       ^
d.cc:3:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
1 error generated.

We can get back the default constructor, without having to write it out explictly, by just doing:

#include <string>

struct F
{
   std::string s{} ;
   
   F( int n ) : s( n, 'a' ) {}

   F() = default ;
} ;

F x ;

It wouldn’t be a big deal to define an explicit default constructor above, just

    F() : s{} {}

but for a more complex class, being able to let the compiler do the work is nicer. Using = default also
means that the redundancy of specifying a member initializer and also having to specify the same initializer
in the default constructor member list is not required, which is nicer.

Note that like ‘= default’, you can use ‘= delete’ to tell the compiler not to generate any default for the member (or template specialization, …) if it would have if left unrestricted. This is similar to the trick of making destructors private:

class foo
{
   ~foo() ;
public:
// ...
} ;

Instead in c++11, you can write

class foo
{
public:
   ~foo() = delete ;
// ...
} ;

so instead of the compiler telling you there is unsufficent access to call the destructor, it should be able to tell you that an attempt to use a destructor for a class that has not defined one has been attempted. Note that this can be an explicitly deleted destructor, or one implicitly deleted (see below).

move operations

Back in university I once wrote a matrix class that I was proud of. It was reference counted to avoid really expensive assignment and copy construction operations, which were particularily bad for any binary operation that returned a new value

template <class T>
matrix<T> operator + ( const matrix<T> & a, const matrix<T> & b ) ;

C implementations of an addition operation (like the blas functions), wouldn’t do anything this dumb. Instead they use an interface like

template <class T>
void matrixadd( matrix<T> & r, const matrix<T> & a, const matrix<T> & b ) ;

This doesn’t have the syntactic sugar, but the performance won’t suck as it would if reference counting wasn’t used. I recall having a lot of trouble getting the reference counting just right, and had to instrument all my copy constructors, assignment operators and destructors with trace logging to get it all right. Right also depended on the compiler that was being used! I’ve still got a copy of that code kicking around somewhere, but it can stay where it is out of sight since move operations obsolete it all.

With move constructor and assignment operators, I was suprised to see them not kick in. These were the move operations

/// A simple square matrix skeleton, with instrumented copy, move, construction and destruction operators
class matrix
{
   using T = int ;                  ///< allow for easy future templatization.

   size_t            m_rows ;       ///< number of rows for the matrix.  May be zero.
   size_t            m_columns ;    ///< number of columns for the matrix.  May be zero.
   std::vector<T>    m_elem ;       ///< backing store for the matrix elements, stored in row major format.

public:

   /// move constructor to create 
   matrix( matrix && m )
      : m_rows{ m.m_rows }
      , m_columns{ m.m_columns }
      , m_elem{ std::move(m.m_elem) }
   {  
      m.m_rows = 0 ;
      m.m_columns = 0 ;
      //std::cout << "move construction: " << &m << " to " << this << " ; dimensions: (rows, columns, size) = ( " << rows() << ", " << columns() << ", " << m_elem.size() << " )\n" ;
   }

   /// move assignment operator.
   matrix & operator = ( matrix && m )
   {  
      //std::cout << "move operator=(): " << this << '\n' ;

      std::swap( m_columns, m.m_columns ) ;
      std::swap( m_rows, m.m_rows ) ;
      std::swap( m_elem, m.m_elem ) ;

      return *this ;
   }

   /// Create (dense) square matrix with the specified diagonal elements.
   matrix( const std::initializer_list<T> & diagonals )

//...
} ;

With the following code driving this

matrix f() ;
   
int m1()
{ 
   matrix x1 = f() ; 
   matrix x2 { f() } ;
      
   return x1.rows() + x2.rows() ;
}     

I was suprised to see none of my instrumentation showing for the move operations. That appears to be because the compiler is doing return value optimization, and constructing these in place in the stack storage locations of &x1, and &x2.

To get actual move construction, I have to explicitly ask for move, as in

matrix mg( {4, 5, 6} ) ;

int m0()
{
   matrix x2 { std::move( mg ) } ;

   return x2.rows() ;
}

and to get move assignment I could assign into a variable passed by reference, like

void g( matrix & m )
{
   m = matrix( {1,2,3} ) ;   
}

This resulted in a stack allocation for the diagonal matrix construction, then a move from that. For this assignment, the compiler did not have to be instructed to use a move operation (and the function was coded explicitly to prevent return value optimization from kicking in).

Note that if any of a copy, move, or destructor is defined for the class, a standards compliant compiler is supposed to also not generate any default copy, move or destructor for the class (i.e. having any such function, means that all the others are =delete unless explicitly defined).

Strange operator overload options

In a table of overloadable operators I see two weird ones:

  • ,
  • ->*

I’d never have imagined that there would be a valid reason to overload the comma operator, which I’ve only seen used in old style C macros that predated C99’s inline support. For example you could do

#define foo(x)    (f(x), g(x))

which might be equivalent to, say,

static inline int foo( int x )
{
   f( x ) ;

   return g(x) ;
}

However, sure enough a comma overloaded function is possible:

struct foo
{
   int m ;

   foo( int v = {} ) : m{v} {}

   int blah( ) const
   {
      return m + 3 ;
   }

   int operator,(const foo & f) 
   {
      return blah() + f.blah() ;
   }
} ;

int main()
{
   foo f ;
   foo g{ 7 } ;

   return f, g ;
}

This results in 7 + 0 + 3 + 3 = 13 as a return code. I don’t have any intention of exploiting this overloadable operator in any real code that I am going to write.

What is the ->* operation that can also be overloaded.

User defined literals

C++11 allows for user defined literal suffixes for constant creation, so that you could write something like

length v = 1.0009_m + 3_dm + 5.0_cm + 7_mm ;

User defined literals must begin with underscore. The system defined literals (such as the complex i, and the chrono ns from c++14) do have this underscore restriction. This is opposite to the user requirement that states no non-system code should define underscore or double-underscore prefixed symbols. I found getting the syntax right for such literals was a bit finicky. The constructor has to be constexpr, and you have to explicitly use long double or unsigned long long types in the operator parameters, as in

struct length
{
   double len {} ;

   constexpr length( double v ) : len{ v } {}
} ;

inline length operator + ( const length a, const length b )
{
   return length( a.len + b.len ) ;
}

constexpr length operator "" _m( long double v )
{
   return length{ static_cast<double>(v) } ;
}

constexpr length operator "" _dm( long double v )
{
   return length{ static_cast<double>(v/10.0) } ;
}

constexpr length operator "" _cm( long double v )
{
   return length{ static_cast<double>(v/100.0) } ;
}

constexpr length operator "" _mm( long double v )
{
   return length{ static_cast<double>(v/1000.0) } ;
}

constexpr length operator "" _m( unsigned long long v )
{
   return length{ static_cast<double>(v) } ;
}

constexpr length operator "" _dm( unsigned long long v )
{
   return length{ static_cast<double>(v/10.0) } ;
}

constexpr length operator "" _cm( unsigned long long v )
{
   return length{ static_cast<double>(v/100.0) } ;
}

constexpr length operator "" _mm( unsigned long long v )
{
   return length{ static_cast<double>(v/1000.0) } ;
}

string literals

It’s mentioned in the book that one can use an s suffix for string literals so that they have std::string type. However, what isn’t stated is that this requires both c++14 and the use of the std::literals namespace. The following illustrates how this feature can be used

#include <string>
#include <iostream>

static_assert( __cplusplus >= 201402L, "require c++14 for string literal suffix" ) ;

using namespace std::literals ;

int main()
{
   std::string hi { "hi\n" } ;
   hi += "there"s + "\n" ;

   std::cout << hi ;

   return 0 ;
}

Note that without the literal s suffix in the string concatonation, as in

   hi += "there" + "\n" ;

This produces an error:

$ make
c++ -o d -std=c++14 d.cc
d.cc:11:18: error: invalid operands to binary expression ('const char *' and 'const char *')
   hi += "there" + "\n" ;
         ~~~~~~~ ^ ~~~~
1 error generated.
make: *** [d] Error 1

The language isn’t designed to know to promote the right hand side elements to std::string just because they are being assigned to such a type. The use of either the string literal suffix, or an explicit conversion is required, as in

hi += std::string{"there"} + "\n" ;

More C++11 notes from reading Stroustrup: nothrow, try, inline & unnamed namespace, initialized new

June 16, 2016 C/C++ development and debugging. No comments , , , , , , , , , , , , , , ,

Here’s more notes from reading Stroustrup’s “The C++ Programming Language, 4th edition”

throw() as noexcept equivalent

throw() without any exception types can be used as an equivalent to the new noexcept keyword. Stroustrup also mentions that explicit throw() clauses

void foo() throw( e1, e2 ) ;

haven’t worked out well in practise, and is deprecated.

try scopes as function body

It turns out that try clauses can be used as function bodies, as in

void foo( void )
try {
}
catch ( ... )
{
}

This can also be done for constructor and destructor bodies as in

X::X( T1 v, T2 w )
try{
 : f1( v )
 , f2( w )
}
catch ( ... )
{
}

so that a throw in the class field member construction can also be caught.

Inline (default) namespace

There is a mechanism for namespace versioning. Suppose that you want a new V2 namespace to be the default, you can do:

namespace myproject
{
   inline namespace V2
   {
      struct X { 
         int x ;
         int y ;
      } ;
      void foo( const X & ) ;
   } 

   namespace V1
   {
      struct X { 
         int x ;
      } ;

      void foo( const X & ) ;
   } 
} 

Existing callers of the library that are using V1 interfaces can continue to work unmodified, but new callers will use the V2::X and V2::foo interfaces, and the library can provide both interfaces, one for compatibility and another for new code:

void myproject::V2::foo( const myproject::V2::X & )
{
   // ...
}

void myproject::V1::foo( const myproject::V1::X & )
{
   // ...
}

Unnamed namespaces.

I’d once seen unnamed namespaces as a modern C++ (more general) replacement for static functions. To see if such namespace functions are optimized away in the same fashion as a static function, I tried

#include <stdio.h>

namespace
{
   void foo()
   {
      printf( "ns:foo\n" ) ;
   }
}

int main() 
{
   foo() ;

   return 0 ;
}

This example uses printf and not std::cout because I wanted to look at the assembly listing and cout’s listing, at least on a mac, was completely abysmal. foo() was optimized away, but that’s a lot easier to see in the C printf listing:

$ make
c++ -o n -std=c++11 -O2 n.cc

$ otool -tV n | less
n:
(__TEXT,__text) section
_main:
0000000100000f70        pushq   %rbp
0000000100000f71        movq    %rsp, %rbp
0000000100000f74        leaq    0x2b(%rip), %rdi        ## literal pool for: "ns:foo"
0000000100000f7b        callq   0x100000f84             ## symbol stub for: _puts
0000000100000f80        xorl    %eax, %eax
0000000100000f82        popq    %rbp
0000000100000f83        retq

at_quick_exit

There’s now also a mechanism to exit and avoid global destructors and atexit routines from being evaluated. Here’s an example

#include <cstdlib>
#include <iostream>

extern "C"
void normalexit()
{
   std::cout << "normalexit\n" ;
}

extern "C"
void quickCexit()
{
   std::cout << "quickCexit\n" ;
}

void quickCPPexit()
{
   std::cout << "quickCPPexit\n" ;
}

class X
{
public:
   ~X()
   {
      std::cout << "X::~X()\n" ;
   }
} x ;

int main( int argc, char ** argv )
{
   atexit( normalexit ) ;
   std::at_quick_exit( quickCexit ) ;
   std::at_quick_exit( quickCPPexit ) ;

   if ( argc == 1 )
   {
      std::quick_exit( 3 ) ;
   }

when run without arguments (argc == 1), we get

$ ./at
quickCPPexit
quickCexit

whereas if the normal exit processing is allowed to complete we see global destructors and regular atexit calls

$ ./at 1
normalexit
X::~X()

Observe, unlike atexit, which can only (portably) take extern “C” defined functions, at_quick_exit can take functions with both C and C++ linkage.

Enum default

It was not obvious to me what the default value for an enum class (or enum) should be (the first value, an invalid value, zero, …)? It turns out that the default is zero, as printed by the following fragment

#include <iostream>

enum class x { v = 1, w } ;
enum y { vv = 1, ww } ;

int main()
{
   x e1 = {} ;
   y e2 = {} ;
   std::cout << (int)e1 << '\n' ;
   std::cout << e2 << '\n' ;

   return 0 ;
}

Note that an explicit cast is required for enum class values, but not for enum, which are by default, int convertible.

default initialization with new

The uniform initializer syntax can also be used with new calls. Here’s an example with uninitialized and default initialized double allocations

#include <stdio.h>

int main()
{
   double * d1 = new double ;
   double * d2 = new double{} ;

   printf( "%g %g\n", *d1, *d2 ) ;

   return 0 ;
}

Observe that we get nice garbage values for *d1, but *d2 is always 0.0:

$ ./d
-1.49167e-154 0
$ ./d
0 0
$ ./d
1.72723e-77 0
$ ./d
-2.68156e+154 0

initializer_list

I remember really wanting a feature like this eons ago when I first wrote a matrix template class in 1st year. Here’s a sample of how it could be used

#include <iostream>
#include <vector>
#include <string>

template <unsigned r, unsigned c>
class m
{
    std::vector<double> mat ;

public:
    class bad_init {} ;
    
    m() : mat(r*c) {}

    m( std::initializer_list<double> i ) : mat( r * c ) 
    {
        if ( i.size() > ( r * c ) )
        {
            throw bad_init() ;
        }

        int p{} ;
        for ( auto v : i )
        {
            mat[ p++ ] = v ;
        }
    }

    void dump( const std::string & n ) const
    {
        const char * sep = ": " ;
        std::cout << n ;

        for ( auto v : mat )
        {
            std::cout << sep << v ;
            sep = ", " ;
        }

        std::cout << '\n' ;
    }
} ;

int main()
{
    m< 3, 2 > v1 ;
    m< 3, 2 > v2{ 0., 1., 2., 3., 4. } ;

    v1.dump( "v1" ) ;
    v2.dump( "v2" ) ;

    m< 3, 2 > v3{ 0., 1., 2., 3., 4., 5., 6., 7. } ;

    return 0 ;
}

This produces the two dumps and the expected std::terminate call for the wrong (too many) parameters on the third construction attempt

$ ./i
v1: 0, 0, 0, 0, 0, 0
v2: 0, 1, 2, 3, 4, 0
libc++abi.dylib: terminating with uncaught exception of type m<3u, 2u>::bad_init
Abort trap: 6

intel memory model talk

June 11, 2016 C/C++ development and debugging. No comments , ,

I just watched an intel-at-google talk on memory model from right around the days that they were putting in the much clarified memory ordering text into the ISA document.

These slides and the talk do a nice job of explaining the significance of a somewhat obscure point in the ISA document:

  • Locked instructions have a total order.

(See ISA Vol 3a-part1, chapter 8.2 Multiple-Processor Management)

The subtlety of this point previously escaped me, and the implication of this is the effect of lock instructions to different memory addresses will always be observed in a specific order.  I’ve always thought of intel LOCKed instructions as a way of implementing something like an powerpc LWARX/STWCX. pair, but this powerpc instruction pair has no implied ordering with respect to any other addresses other than the one that it is operating on.  On powerpc such ordering is really only possible in a pairwise fashion by inserting fencing instructions (LWFENCE and ISYNC typically).  I’m not sure of a way, on powerpc, of obtaining such a total ordering as the intel LOCKed instructions provide.

stack corruption detection with clang: safe-stack notes

June 10, 2016 C/C++ development and debugging. No comments , , ,

At LZ our development and nightly builds are done with clang, so it is of interest to check out what stack protection checking compiler options are available.  DB2 LUW used the intel compiler, which had very nice stack clobbering code.  How does clang’s fair against the intel compiler in this respect?

Clang does support a safe-stack option.  Here’s an example of some stack corrupting code:

#include <string.h>

void corrupt( char * b ) ;

int main()
{
   char b[12] ;

   corrupt( b ) ;

   return 0 ;
}

void corrupt( char * b )
{
   memset( b - 4, 'a', 20 ) ;
}

Running this without safe stack results in a SEGV on return from from corrupt():

Screen Shot 2016-06-10 at 11.08.54 AM

with safe-stack we have a “nicer” trap:

(gdb) run
Starting program: /home/pjoot/lznotes/proto/stackcorrupt2
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
__memset_sse2 () at ../sysdeps/x86_64/memset.S:415
415     L(P4Q0): mov    %edx,-0x4(%rdi)
Missing separate debuginfos, use: debuginfo-install libgcc-4.8.3-9.el7.x86_64 libstdc++-4.8.3-9.el7.x86_64
(gdb) where
#0  __memset_sse2 () at ../sysdeps/x86_64/memset.S:415
#1  0x0000000000411835 in corrupt (
    b=0x7ffff6bd2ff4 'a' <repeats 12 times>, "\177ELF\002\001\001\003")
    at stackcorrupt2.cc:16
#2  0x00000000004117f1 in main () at stackcorrupt2.cc:9

The compiler is able to catch the corruption in the act, right in the offending memset.

Limitations

What I do notice with this compiler option, is that the implementation has opted not to catch corruptions within the valid stack frame, nor is there any attempt to catch a corruption that does not walk over the return pointer. Here’s an example:

#include <string.h>

void corrupt( char * b ) ;

#define SZ 12
#if 0
   // safe-stack catches this:
   #define PRESZ 0
   #define POSTSZ 4
#else
   // safe-stack catches this buffer overwrite
   #define PRESZ 4
   #define POSTSZ 0
#endif
int main()
{
   char b[SZ] ;

   corrupt( b ) ;

   return 0 ;
}

void corrupt( char * b )
{
   memset( b - PRESZ, 'a', SZ + PRESZ + POSTSZ ) ;
}

and another non-trapping stack corruption:

#include <stdio.h>
#include <string.h>

void corrupt2( int & a, char * b, int & c ) ;

int main()
{
   int a = 0 ;
   char b[12] ;
   int c = 0 ;

   corrupt2( a, b, c ) ;

   printf( "0x%08X 0x%08X\n", a, c ) ;

   return 0 ;
}

void corrupt2( int & a, char * b, int & c )
{
   memset( b - 4, 'a', 20 ) ;
}

The intel compiler appeared to use guard bytes between stack variables, and was able to tell you exactly which stack variable was overwritten. Clang appears to be opting for a write-forbidden guard region on the stack frame, so it able to catch the corruption in the act, but only if the corruption is “big enough”. There are benefits of both approaches. Unfortunately, there are a number of restrictions in the safe-stack documentation. I’m not sure that I’ll be able to use this at all in LZ code.

gdb TUI mode debugging

June 9, 2016 C/C++ development and debugging. 1 comment , , ,

I recently watched Greg Law’s “I’ll change your opinion on GDB” talk from CPPCON 2015, where he gave a nice example of how to use the gdb TUI (text user interface) mode. I’d recently encountered the gdb –tui option, but thought that you had to have the foresight to remember to invoke gdb with –tui (which I usually didn’t, but also didn’t always want to since it’s redraw was flaky in a putty terminal session).

It turns out that there are command line keystrokes to enable TUI dynamically when you want it (or turn it off when you don’t). That makes this TUI a much nicer feature!

The main key commands of interest are:

– C-x a, turn on (or off) TUI mode.
– C-x 2. Use two windows, or cycle to the next layout.
– C-x o. Change active window.
– C-L

Here’s an example how things look after turning on TUI (C-x a):

Screen Shot 2016-06-09 at 7.42.59 PM

After turning on two window mode (C-X 2):

Screen Shot 2016-06-09 at 7.44.05 PM

This has a source view, an assembly view, and the output of ‘info registers’.  You can actually get a register window by cycling through the window layouts once (C-x 2 again) :

 

Screen Shot 2016-06-09 at 7.44.40 PM

Some of the previous times that I’d tried ‘gdb –tui’ explicitly, I’d found it hit redraw issues, but didn’t really want to detach and reattach the debugger just to change the TUI mode.  It sounds like such issues can be dealt with either by turning off TUI mode (C-x a), or using redraw (C-L).

Notes for Stroustrup’s “The C++ Programming Language, 4th Ed.”: nothrow new, noexcept, noreturn, static cons, initializer_list

June 8, 2016 C/C++ development and debugging. No comments , , , , , , , ,

I recently purchased Stroustrup’s C++11 book [1], after borrowing it a number of times from the Markham public library (it’s very popular, and only offered for short term loan) . Here are some notes of some bits and pieces that were new to me for this round of reading.

nothrow new

In DB2 we used to have to compile with -fcheck-new or similar, because we had lots of code that predated new throwing on error (c++98). There is a form of new that explicitly doesn’t throw:

void * operator new( size_t sz, const nothrow_t &) noexcept ;

I don’t know if this was introduced in c++11. If this was a c++98 addition, then it should be used in almost all the codebases new calls. When I left DB2 there were still some platform compilers (i.e. AIX xlC which doesn’t use the clang front end like linuxppcle64 xlC) that were not c++11 capable, so if this explicit nothrow isn’t c++98, it probably can’t be used.

Unnamed function parameters

It is common to see function prototypes without named parameters, such as

void foo( int, int ) ;

I did not realize that is also possible in the function definition, as in code like the following where a parameter has been dropped or left as a placeholder for future use

void foo( int x, int )
{
   printf( "%d\n", x ) ;
}

Not naming the parameter is probably a good way to get rid of unused parameter warnings.

This is very likely not a c++11 addition. I just didn’t realize the language allowed for it, and had never seen it done.

No return attribute

Looks like __attribute__ extensions are being baked right into the language, as in

[[noreturn]] void exit( int ) ;

I wonder if this is also in the plan for C?

Thread safe static constructors

C++11 explicitly requires static variable constructors are initialized using a “call-once” mechanism

class x
{
public: 
   x() ;
} ;

void foo( void )
{
   static x v() ;
}

Here there is no data race if foo() is executed concurrently in a number of threads. I remember seeing DB2 code that did this (and opening a defect to have it “fixed”), since I had no idea if it would work. We didn’t (and couldn’t yet) use -std=c++11, so it’s anybody’s guess what that does without that option and on older pre c++11 compilers.

Implied type initializer lists.

In a previous post I mentioned the c++11 uniform initialization syntax, but the basic idea is that is instead of

int x(1) ;
int y(0) ;

or

int x = 1 ;
int y = 0 ;

c++11 now allows

int x{1} ;
int y{} ;

Here the variables are initialized with values 1, and 0 (the default). The motivation for this was to provide an initializer syntax that could be used with container classes. Here’s another variation on the initializer list initialization

int x = int{} ;
int y = int{3} ;

which can be reduced to

int x = {} ;
int y = {3} ;

where the types of the lists are implied. I don’t see much value add to use this equals-list syntax in the examples above. Where this might be useful is in templated code to provide defaults

template <typename T>
void foo( T x, T v = {} ) ;

Runtime values for default arguments.

I don’t know if this is new to C++11, but the book points out that default arguments can be runtime determined values. Initially, my thought on this was that it is good that is not well known, since it would be confusing. I did however, come up with a scenerio where this could be useful. I wrote some code like the following the other day

extern bool g ;

inline int foo( )
{
   int res = 0 ;

   if ( g )
   {
      // first option
   }
   else
   {
      // second option
   }

   return res ;
}

The global g was precomputed at the shared library startup point (effectively const without being marked so). My unit test of this code modified the value of g, which was a hack and I admit ugly. It looked like

BOOST_AUTO_TEST_CASE( basicTest )
{
   for ( auto b : {false, true} )
   {
      g = b ;

      int res = foo() ;

      BOOST_REQUIRE( res >= 0 ) ;
   }
}

This has a side effect of potentially changing the global. A different way to do this would have been

extern bool g ;

inline int foo( bool internalOverrideOfGlobalForTesting = g )
{
   int res = 0 ;

   if ( internalOverrideOfGlobalForTesting )
   {
      // first option
   }
   else
   {
      // second option
   }

   return res ;
}

The test code could then be rewritten as

BOOST_AUTO_TEST_CASE( basicTest )
{
   for ( auto b : {false, true} )
   {
      int res = foo( b ) ;

      BOOST_REQUIRE( res >= 0 ) ;
   }
}

This doesn’t touch the global (an internal value), but still would have allowed for testing both codepaths. The fact that this “feature” exists may not actually be in this case, since my interface was a C interface. Does a

noexcept

Functions that intend to provide a C interface can use the noexcept keyword. That allows the compiler to enforce the fact that such functions should provide a firewall that doesn’t let any exceptions through. Example:

// foo.h
#if defined __cplusplus
   #define EXTERNC extern "C"
   #define NOEXCEPT noexcept
#else
   #define EXTERNC
   #define NOEXCEPT
#endif

EXTERNC void foo(void) NOEXCEPT ;

// foo.cc
#include "foo.h"
int foo( void ) NOEXCEPT
{
   int rc = 0 ;
   try {
      //
   }
   catch ( ... )
   {
      // handle error
      rc = 1 ;
   }

   return rc ;
}

If foo does not catch all exceptions, then the use of noexcept will drive std::terminate(), like a throw from a destructor does on some platforms.

References

[1] Bjarne Stroustrup. The C++ Programming Language, 4th Edition. Addison-Wesley, 2014.

Integer square root

June 4, 2016 C/C++ development and debugging. No comments , , ,

Screen Shot 2016-06-04 at 10.39.47 PM

[Click here for a PDF of this post with nicer formatting]

In [1] is a rather mysterious looking constant expression formula for an integer square root. This is a function that returns the smallest integer for which the square is less than the value to take the root of. Check out the black magic he used

// Stroustrup 10.4:  constexpr capable integer square root function
constexpr int isqrt_helper( int sq, int d, int n )
{
	return sq <= n ? isqrt_helper( sq + d, d + 2, n ) : d ;
}

constexpr int isqrt( int n )
{
	return isqrt_helper( 1, 3, n )/2 - 1 ;
}

The point of this construction was really to illustrate that it allows complex expressions to be used as compile time constants. I wonder at what point various compilers will give up trying to evaluate such expressions?

Let’s take this apart a bit.

Consider the first few values of \( n > 0 \).

  • \( n = 0 \). Here we have a call to \( \textrm{isqrt_helper}( 1, 3, 0 ) \) so the \( 1 \le 0 \) predicate is false, and the return value is just \( 3 \).

    For that value we have (using integer arithmetic):

    \begin{equation}\label{eqn:isqrt:20}
    \frac{3}{2} – 1 = 0,
    \end{equation}

    as desired.

  • \( n = 1 \). Here we have a call to \( \textrm{isqrt_helper}( 1, 3, 1 ) \) so the \( 1 \le 1 \) predicate is true, resulting in a second call \( \textrm{isqrt_helper}( 4, 5, 1 ) \). For that call the \( 4 \le 1 \) predicate is false, resulting in a return value of \( 5 \).

    This time we have a final result of

    \begin{equation}\label{eqn:isqrt:40}
    \frac{5}{2} – 1 = 1,
    \end{equation}

    as desired again. The result will be the same for any value \( n \in [1,3] \).

  • \( n = 4 \). We will end up with a call to \( \textrm{isqrt_helper}( 4, 5, 4 ) \) for which the \( 4 \le 4 \) predicate is true, resulting in a followup call of \( \textrm{isqrt_helper}( 9, 7, 4 ) \). For that call the \( 9 \le 4 \) predicate is false, resulting in a return value of \( 7 \).

    This time we have a final result of

    \begin{equation}\label{eqn:isqrt:45}
    \frac{7}{2} – 1 = 2,
    \end{equation}

    as expected. We get the same result for any value \( n \in [4,8] \).

Recurrence relations

The rough pattern of the magic involved can be seen. We have a sequence of calls

  • \( \textrm{isqrt_helper}( 1, 3, n ) \),
  • \( \textrm{isqrt_helper}( 4, 5, n ) \),
  • \( \textrm{isqrt_helper}( 9, 7, n ) \),
  • \( \textrm{isqrt_helper}( 16, 9, n ) \),

which terminates at the point where the first (square) parameter exceeds that value that we are taking the root of. Let the parameters of the sequence of calls be \( s_k \), and \( d_k \), so that with \( s_0 = 1, d_0 = 3 \) the \( k \in [0,…] \) call to the helper function is \( q_k = \textrm{isqrt_helper}( s_k, d_k, n ) \).

The sequence for the second parameter, the eventual return value, can be summarized compactly as \( d_k = 3 + 2 k \). It is not entirely obvious how we end up with a square for the values \( s_k = s_{k-1} + d_{k-1} \), but this follows by summation. For \( k > 1 \) that is

\begin{equation}\label{eqn:isqrt:60}
\begin{aligned}
s_k
&= s_{k-1} + d_{k-1} \\
&= s_0 + d_0 + d_1 + d_{k-1} \\
&= s_0 + \sum_{m=0}^{k-1} d_m \\
&= s_0 + \sum_{m=0}^{k-1} (3 + 2 m ) \\
&= s_0 + \sum_{m=1}^{k} (3 + 2 (m-1) ) \\
&= s_0 + \sum_{m=1}^{k} (1 + 2 m ) \\
&= 1 + k + 2 \sum_{m=1}^{k} m \\
&= 1 + k + 2 \frac{k(k+1)}{2} \\
&= k^2 + 2 k + 1 \\
&= (k+1)^2.
\end{aligned}
\end{equation}

This clearly holds for the boundary cases \( k = 0,1 \) as well. This allows the helper function action to be summarized more compactly

\begin{equation}\label{eqn:isqrt:80}
\textrm{isqrt_helper}(1, 3, n) = 3 + 2 k,
\end{equation}

where \( k \) is the smallest integer such that \( (k+1)^2 > n \). After integer scaling the final result is

\begin{equation}\label{eqn:isqrt:100}
(3 + 2 k)/2 -1 = k.
\end{equation}

This little beastie makes sense after deconstruction, but it was very Jackson like to toss this into the book without comment or explanation.

As pointed out by Pramod Gupta, there’s a spooky appearance of collaboration between Stroustrup and Jackson’s publishers, not entirely limited to the book covers.

References

[1] Bjarne Stroustrup. The C++ Programming Language, 4th Edition. Addison-Wesley, 2014.