/* */ /* */

Friday, October 12, 2012

Posting C++ Code

I decided that if I'm going to be posting code, I might as well figure out how to make it look like code. In a comment on my last post, Nuno Barreiro's suggested I use SyntaxHighlighter, so I decided to give it a try.

Never in the history of software development has there been a tool with more explicit no-brains-are-required installation and usage tutorials.  My favorite is this one, because, really, how much more can you ask than for screen shots with arrows pointing where to click and "Click this" directives?  I threw caution to the wind and did exactly as I was told. Security be damned, I wanted my code to be syntax-highlighted, and I was in a hurry!

It didn't work.  The syntax of my code was not highlighted, and I got an error telling me that the brush I needed couldn't be found. An hour or so of googling and trial and error and more googling and more trial and more error ensued before I figured out that the name of the brush I needed was "c++", not "C++". That despite the fact that the documented brush name is "C++" and the name of the JavaScript file is shBrushCpp.js.  (Alias brush names are "cpp" and "c", both of which also work, but by the time I started playing around with the aliases, I was beyond noticing that the file name contained "Cpp", but the alias is "cpp".  My bad.)

To get code to display properly, you have to enter it in HTML mode (at least in Blogger, which is the platform I'm using), and you have to remember to transform all opening angle brackets ("<") into their fetching HTML equivalents ("&lt;"). I use Centricle.com's Encode/Decode HTML Entities page for that.

To get C++ code highlighting in Blogger, then (and I'm posting this here more for me than in the hope it might be useful to somebody else) you first blindly point, click, copy, and configure as per this page (initial setup) and this page (additional configuration). For each code fragment you want to appear in your blog, you:
  1. Write the code elsewhere, presumably where you can easily edit and test it. I use Emacs, but I've heard tell that there are other code and text editors.
  2. Transform the code into HTML-friendly form via something like the Encode/Decode HTML Entities page.
  3. Copy the transformed code into the HTML editor in Blogger.  Put said code into a pre block as follows:
<pre class="brush: c++">
Your code goes here
</pre>
In the words of technical support professionals everywhere, it works for me.

As a demonstration, here's some code I've been playing around with this evening.  The goal is to see which of several potential constructors is called when an object (an lvalue, if you insist on knowing) is copied. Try to predict what it will do before you feed it to your compiler. When I run it under gcc 4.7, I'm surprised by what I see.
#include <iostream>

class Widget {
public:
  Widget(){};

  Widget(const Widget&) { std::cout << "Widget copy ctor  "; }

  template<typename T>
  Widget(const T&) { std::cout << "Generalized Widget copy ctor  "; }

  template<typename T>
  Widget(T&&) { std::cout << "Universal Widget ctor  "; }
};


void endLine() { std::cout << '\n'; }


int main()
{
  Widget w;

  {
    std::cout << "Create Widget from Widget:\n";
    std::cout << "  Direct init w/parens: ";   Widget wcopy1(w);  endLine();
    std::cout << "  Copy init           : ";   Widget wcopy2 = w; endLine();
    std::cout << "  Direct init w/braces: ";   Widget wcopy3 {w}; endLine();
    endLine();
  }


  {
    std::cout << "Create auto from Widget:\n";
    std::cout << "  Direct init w/parens: ";   auto wcopy1(w);   endLine();
    std::cout << "  Copy init           : ";   auto wcopy2 = w;  endLine();
    std::cout << "  Direct init w/braces: ";   auto wcopy3 {w};  endLine();
    endLine();
  }

  const Widget cw;

  {
    std::cout << "Create Widget from const Widget:\n";
    std::cout << "  Direct init w/parens: ";   Widget wcopy1(cw);  endLine();
    std::cout << "  Copy init           : ";   Widget wcopy2 = cw; endLine();
    std::cout << "  Direct init w/braces: ";   Widget wcopy3 {cw}; endLine();
    endLine();
  }

  {
    std::cout << "Create auto from const Widget:\n";
    std::cout << "  Direct init w/parens: ";   auto wcopy1(cw);   endLine();
    std::cout << "  Copy init           : ";   auto wcopy2 = cw;  endLine();
    std::cout << "  Direct init w/braces: ";   auto wcopy3 {cw};  endLine();
    endLine();
  }
}
Update 10/17/12: Having run across this blog post, I also gave Google's Prettify a try. I don't like the result as well as that of SyntaxHighlighter, but judge for yourself.  Here's a prettified version of the Widget class above:
class Widget {
public:
  Widget(){};

  Widget(const Widget&) { std::cout << "Widget copy ctor  "; }

  template<typename T>
  Widget(const T&) { std::cout << "Generalized Widget copy ctor  "; }

  template<typename T>
  Widget(T&&) { std::cout << "Universal Widget ctor  "; }
};

14 comments:

Anonymous said...

Adding an explicit move constructor makes this example a little bit more interesting.

Anonymous said...

There are of course loads of alternatives floating around on the net. One such alternative that I'm fond of is http://ideone.com (I have no connection with them)

It is Dead simple to use. Just enter the code, press submit and then copy the produced code-snippet into your html page. Done.

As a preeetty nice bonus, in addition to syntax highlighting the c++ source code, it compiles it too! And it even runs it!! How awesome isn't that! Ohh, and you do not have to use any HTML entities conversion tools...

Klaim said...

Anonymous, the point is to put code into an article, not outside of it.

Scott, did you explore the other blogging alternatives? I suppose not because it would be such a waste of your time!

Manuel said...

Regarding posting C++ code, it is useful adding line numbering for the purpose of commentaries reference.

Julian said...

FWIW, the output seems to be compiler dependent:

$ g++ -std=c++11 -o test test.cpp
$ ./test
Create Widget from Widget:
Direct init w/parens: Universal Widget ctor
Copy init : Universal Widget ctor
Direct init w/braces: Universal Widget ctor

Create auto from Widget:
Direct init w/parens: Universal Widget ctor
Copy init : Universal Widget ctor
Direct init w/braces: Universal Widget ctor Universal Widget ctor

Create Widget from const Widget:
Direct init w/parens: Widget copy ctor
Copy init : Widget copy ctor
Direct init w/braces: Widget copy ctor

Create auto from const Widget:
Direct init w/parens: Widget copy ctor
Copy init : Widget copy ctor
Direct init w/braces: Widget copy ctor Universal Widget ctor


$ clang++ -std=c++11 -o test test.cpp
$ ./test
Create Widget from Widget:
Direct init w/parens: Universal Widget ctor
Copy init : Universal Widget ctor
Direct init w/braces: Universal Widget ctor

Create auto from Widget:
Direct init w/parens: Universal Widget ctor
Copy init : Universal Widget ctor
Direct init w/braces: Universal Widget ctor

Create Widget from const Widget:
Direct init w/parens: Widget copy ctor
Copy init : Widget copy ctor
Direct init w/braces: Widget copy ctor

Create auto from const Widget:
Direct init w/parens: Widget copy ctor
Copy init : Widget copy ctor
Direct init w/braces: Widget copy ctor


Seems g++ still has some portential for optimiziation here.

Scott Meyers said...

@Klaim: I chose Blogger a while ago, and I don't want to invest the time to revisit that decision right now. So I'm looking for something that's easy and that works with Blogger. SyntaxHighlighter may not be optimal, but it's not bad.

Scott Meyers said...

@Manuel: SyntaxHighlighter provides line numbering by default. I find it visually distracting, so I turned it off, but I may change my mind. I agree that having line number can be useful for later discussion, but I generally prefer to put my commentary in the code itself.

Martin Moene said...

To enter code unmodified, you can use <![CDATA[...]]> as described here. It has the drawback though that the code doesn't show in HTML edit mode.

Scott Meyers said...

@Martin Moene: Yes, but note the comment on that page that "if you are using SyntaxHighlighter on a blog, you are better off with the <pre /> method."

wilhelmtell said...

Check out GNU source-highlight. It's a command-line utility that takes source code as input and generates the same code syntax-highlighted.

Nuno Barreiro said...

Hi Scott,

Although I also recognize that SyntaxHighlighter is not the optimal solution that someone could wish for, I'm glad that I helped in some way.

For as long as I can remember, displaying code on blogger has always been somewhat tricky, but I still believe that it is one of the most powerful blogging tools, although with its own imperfections as any tool.

Nuno Barreiro said...
This comment has been removed by the author.
Scott Meyers said...

For the record, I've now updated this post to show an example of what code looks like when formatted via Google Prettify.

Bower said...
This comment has been removed by a blog administrator.