Posts Tagged ‘cplusplus’

Iostreams Re-Examined

Sunday, April 7th, 2013

One area in C++ I had never really spent a lot of time with until early last year is the iostreams library. I *thought* I understood it pretty well. At a superficial level, it made perfect sense: replace printf/scanf with an abstract interface for serialization that objects could implement for themselves.

As a developer whose post-stdio-era coding usually targeted things like graph databases instead of text files, I didn’t have all that many occasions to use iostreams. But as I became more involved in exchanging small conceptual programs with other developers, I realized that they are the “lingua franca” of standard C++. Using them began to teach me that there were many things about them I didn’t know…and that they could be very useful, as well as very tricky.

For instance, do you know the difference between these two lines?

std::cout << std::endl;
std::cout << ‘\n’;

I didn’t! That’s just for starters, so I gave a presentation on the topic to my Austin C/C++ Group in October 2011. In it, I represent some of my new understandings:

Slideshow iconView the presentation

At first, I delayed on publishing it to the Web for fear that it may not be 100% right. But then it languished in a private Google Docs presentation for a year and a half. I found it today, and if I’m worried about its inaccuracy it’s sure not going to get any better by leaving it there. And it might help someone, as I know there are a large number of people on the Internet who are even more less than 100% right. :-P

So here it is, and corrections are of course welcome–just leave a comment!

(Note: Learning the details about this would not have happened without the help of the active C++ community on SO. That’s where I spent most of my recreational programming time—instead of writing blog entries—in 2011. Both asking and answering questions offers insights. While some people seem to have a bit of what amounts to an “online game addiction”, it’s a case where their affliction can benefit you and the common good. :P)

The Essential Noisy Debug Hook for Qt

Tuesday, October 2nd, 2012

If you’re using Qt, you might find that it can often be rather quiet about important and common programming errors. For instance: by default, it considers the inability to connect a signal and a slot—due perhaps to a typographic error—to be a warning worth only quietly pushing into your debug output window. It’s easy to miss, especially if you (or libraries you call) have a lot of monitoring information turned on!

I’m the sort who immediately bumps up every warning level in the compiler to turn them into errors. In a similar vein, I’ve found it useful to throw the following code into the main.cpp of any Qt GUI app I am writing. (Thanks to commenter kkoehne for feedback!)

#ifdef QT_DEBUG
 
#include <QMessageBox>
#include <QThread>
#include <iostream>
 
// By default, fairly big problems like QObject::connect not working due to not being able
// to find a signal or slot goes to the debug output.  There can be a lot of spew which
// makes that easy to miss.  While perhaps the release build would want to try and
// keep going, it helps debugging to get told this ASAP.
//
// Would be nice to chain to the default Qt platform error handler
// However, this is not feasible as there is no "default error handler" function
// The default error handling is merely what runs in qt_message_output
// 	http://qt.gitorious.org/qt/qt/blobs/4.5/src/corelib/global/qglobal.cpp#line2004
//
void noisyFailureMsgHandler(QtMsgType type, const char * msgAsCstring) {
    QString msg (msgAsCstring);
    std::cerr << msgAsCstring;
    std::cerr.flush();
 
    // Why on earth didn't Qt want to make failed signal/slot connections qWarning?
    if ((type == QtDebugMsg)
            && msg.contains("::connect")) {
        type = QtWarningMsg;
    }
 
    // this is another one that doesn't make sense as just a debug message.  pretty serious
    // sign of a problem
    // http://www.developer.nokia.com/Community/Wiki/QPainter::begin:Paint_device_returned_engine_%3D%3D_0_(Known_Issue)
    if ((type == QtDebugMsg)
            && msg.contains("QPainter::begin")
            && msg.contains("Paint device returned engine")) {
        type = QtWarningMsg;
    }
 
    // This qWarning about "Cowardly refusing to send clipboard message to hung application..."
    // is something that can easily happen if you are debugging and the application is paused.
    // As it is so common, not worth popping up a dialog.
    if ((type == QtWarningMsg)
            && QString(msg).contains("QClipboard::event")
            && QString(msg).contains("Cowardly refusing")) {
        type = QtDebugMsg;
    }
 
    // only the GUI thread should display message boxes.  If you are
    // writing a multithreaded application and the error happens on
    // a non-GUI thread, you'll have to queue the message to the GUI
    QCoreApplication * instance = QCoreApplication::instance();
    const bool isGuiThread = 
        instance && (QThread::currentThread() == instance->thread());
 
    if (isGuiThread) {
        QMessageBox messageBox;
        switch (type) {
        case QtDebugMsg:
            return;
        case QtWarningMsg:
            messageBox.setIcon(QMessageBox::Warning);
            messageBox.setInformativeText(msg);
            messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
            break;
        case QtCriticalMsg:
            messageBox.setIcon(QMessageBox::Critical);
            messageBox.setInformativeText(msg);
            messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
            break;
        case QtFatalMsg:
            messageBox.setIcon(QMessageBox::Critical);
            messageBox.setInformativeText(msg);
            messageBox.setStandardButtons(QMessageBox::Cancel);
            break;
        }
 
        int ret = messageBox.exec();
        if (ret == QMessageBox::Cancel)
            abort();
    } else {
        if (type != QtDebugMsg)
            abort(); // be NOISY unless overridden!        
    }
}
#endif

Then in the main() function, after the QApplication is initialized…I’ll say:

#ifdef QT_DEBUG
    // Because our "noisy" message handler uses the GUI subsystem for message
    // boxes, we can't install it until after the QApplication is constructed.  But it
    // is good to be the very next thing to run, to start catching warnings ASAP.
    {
        QtMsgHandler oldMsgHandler (qInstallMsgHandler(noisyFailureMsgHandler));
        Q_UNUSED(oldMsgHandler); // squash "didn't use" compiler warning
    }
#endif

By re-prioritizing the default error levels to something more reasonable and being “noisier” when a serious problem is happening during debugging, it has been a huge time saver. Try it and let me know what you think!

Bjarne Stroustrup on the Uniqueness of unique_ptr

Sunday, September 30th, 2012

I helped organize a talk from Dr. Bjarne Stroustrup in Austin on September 19, 2012. It was a presentation he’s apparently given in some form or another elsewhere, but I had not seen the slides before.

Much of it wasn’t new material for me. I am already familiar with the tenets of “Modern C++”, but he introduced them lucidly for people unfamiliar with concepts like shared_pointer or unique_ptr. I’d also seen his article about type-safety in SI units from IEEE Spectrum.

(Note: What did surprise me was a graph of an experiment he did with the performance of vector vs. list. It also challenged many people’s assumptions about at what size a list would crossover to being faster. The task would seem to benefit substantially from being able to do arbitrary insertions quickly. But it looks like the three most important things in performance are starting to mirror the three most important things in real-estate: Locality, Locality, Locality! :-P)

We didn’t record the talk. It would have been some effort to arrange with the venue, and he told us in advance it would be similar to talks he’s given elsewhere that were online. Yet I should have had the prescience to record the Q&A!

In any case, I did manage to ask him about an issue that had been on my mind for a while:

Do you personally feel that it’s good practice to use unique_ptr as a way of following the “hot potato” of deletion responsibility on an object, while extracting the raw pointer and passing it into other code? Or should unique_ptr live up to its name and always be truly “unique”…the only handle to the pointed-to-object in the system?

In the past, I’ve not really been able to get a consistent view from people on this. So I figured there wasn’t a much better person to ask for an authoritative answer!

He had more moments of pause in answering this than the other questions. He prefaced by saying that he didn’t really think there was enough experience with the issue to really establish what “good” and “bad” practice was going to be in the matter. But he said he could offer his “current opinion”.

That opinion was that it was fine IF the holder of the unique_ptr could guarantee that all of the routines that were passed the extracted pointers were finished before the unique_ptr was moved to be under the control of someone else.

So that’s “from the horse’s mouth” as of September 19, 2012. Off the top of my head, I do remember a couple of other questions…

(more…)

Tweaking Analog Literals (C++ humor)

Saturday, August 29th, 2009

Jeremy Friesner brought this site about analog literals to my attention. It provides the long-needed ability to represent integer constants in C++ not as numbers (like 42) but rather as 1-D, 2-D, or 3-D shapes whose length, area, or volume correspond to the number’s quantity. So for instance:

assert( ( o-------------o
          |L             \
          | L             \
          |  L             \
          |   o-------------o
          |   !             !
          !   !             !
          o   |             !
           L  |             !
            L |             !
             L|             !
              o-------------o ).volume == 
 
( o-------------o
  |             !
  !             !
  !             !
  o-------------o ).area * int(I-------------I) );

That’s great! As the inventor of Arecibo ASCII, I fully support this visual double-check with our intuitions about numbers! What if aliens are trying to read our code, but don’t know about our arbitrary choices of digits and numeric base?? This could bridge that important gap! :P

But there’s one nagging concern I have, which is that I don’t think the 1-D numeric values are very intuitive. Look at these examples from the site:

assert( I-I == 0 );
assert( I---I == 1 );
assert( I-----I == 2 );
assert( I-------I == 3 );

I’d prefer it to more consistently depict the historic concept of zero, and be less arbitrary with the “2N+1″ formula of dashes to implement value N. So why not overload dereference and multiply, and define “II” to be the constant value zero? This way you can get:

assert(II == 0);
assert(I*I == 1);
assert(I**I == 2);
assert(I***I == 3);

The implementation is relatively straightforward from the proposal. But I went ahead and wrote it, and it is complete enough to give errors when compiling invalid literal specifications:

int test1 (I); // compile error!
int test2 (*I); // compile error!
int test3 (I*); // compile error!
int test4 (*I*I); // compile error!
int test5 (I*I*); // compile error!

I hope this makes it more practical for people to apply analog literals to real-world situations! Source below…

(more…)

Cleaner API Design Using Ignorable “Hints”

Friday, August 12th, 2005

Sometimes API authors expose additional entry points to their code which exist only because of performance. For instance, look at why MakeManyWidgets() exists in the sample below:

class WidgetFactory
   {
private:
   // a really, really slow routine
   void StopProcessesSoItsSafeToMakeWidgets();
 
   // another really, really slow routine
   void RestartProcesses();
 
public:
   Widget* MakeAWidget()
      {
      StopProcessesSoItsSafeToMakeWidgets();
      Widget* w = new Widget();
      RestartProcesses();
      return w;
      }
 
   std::vector<Widget*> MakeManyWidgets(int HowMany)
      {
      std::vector<Widget*> ret;
      StopProcessesSoItsSafeToMakeWidgets();
      for (int temp = 0; temp < HowMany; temp++)
          ret.push_back(new Widget());
      RestartProcesses();
      return ret;
      }
 
   void DoSomethingElse()
      {
      assert(ProcessesRunning());
      return;
      }
   };

The extra routine was added as a mere performance convenience, since making N widgets has identical semantics to simply N successive calls to MakeAWidget(). This is presumably safer than publishing the private routines for starting and stopping processes so it’s safe to make widgets—not only might that be an implementation detail we don’t want to expose, it could be deemed too serious a problem if the client improperly matches up stop/start calls.

I’ve seen this pattern countless times, and never liked it. Routines like MakeManyWidgets() lead the clients of your API to start disrupting the control flow in their programs to try and get a performance payoff that may turn out to be irrelevant in the future. It also gives the misleading impression that there might be a semantic significance to creating a set of widgets as a batch, and will make source code written to the API a lot harder to absorb.

If I face a situation like this, I completely decouple the performance “hint” from the routines that do the work. As a rule, I also make sure that if the hint gives blatantly incorrect information, the worst that can happen is that your program is a bit slower than it would have been without the hint. To give an example of how this might work, look at HINT_MakingManyWidgets() below:

class WidgetFactory
   {
private:
   mutable int widgets_hint;
 
private:
   // a really, really slow routine
   void StopProcessesSoItsSafeToMakeWidgets();
 
   // another really, really slow routine
   void RestartProcesses();
 
public:
   void HINT_MakingManyWidgets(int HowMany) const
      {
      widgets_hint += HowMany;
      }
 
   Widget* MakeAWidget()
      {
      if (ProcessesRunning())
         StopProcessesSoItsSafeToMakeWidgets();
      Widget* w = new Widget();
      if (widgets_hint > 0)
         {
         widgets_hint--;
         RestartProcesses();
         }
      return w;
      }
 
   void DoSomethingElse()
      {
      if (!ProcessesRunning())
         {
         widgets_hint = 0;
         RestartProcesses();
         }
      }
   };

This way, developers aren’t encouraged to complicate their code up front. No one will use these HINT_ functions unless they need to—only those clients who are dissatisfied with performance will bother. You can add as many as you like, adapted specifically to suit the real use cases of important clients. And if you ever want to stop supporting a hint you merely make the function have no effect.

The worst you’ll do to your clients is slow them down, and your API and code using it will be purer and more elegant!


Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported