The Fugue Counterpoint by Hans Fugal

6Dec/130

Reduce compilation time with template magic.

It is a common belief that templates must be implemented in header files, a lamentable situation that greatly increases build times because those full-blown headers must be compiled every time they are included. It also makes the headers less useful as brief documentation, which one of the things about headers that is actually good.

But that is not strictly true. You can separate template declarations and implementations. With a simple pattern and just a little thought, you can compile your template code once and link it just like you do regular objects or functions.

Let us begin with a function foo which just prints the T it was given to cout. Here is the header:

// foo.h
#pragma once

template <class T> void foo(T);

Now let's try to use it:

// a.cc
#include "foo.h"

int main(void) {
    foo(42);
    return 0;
}

And compile:

$ c++ -std=c++11 -c a.cc
$ c++ a.o
Undefined symbols for architecture x86_64:
  "void foo<int>(int)", referenced from:
      _main in a.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

The object file compiles fine, but linking fails because void foo<int>(int) is undefined. So, let's define it:

// foo-tmpl.h
#pragma once

#include "foo.h"
#include <iostream>

template <class T> void foo(T t)
{
    std::cout << t << std::endl;
}

Now if we change a.cc to include foo-tmpl.h instead of foo.h, the implicit instantiation will work fine. But instead, let's explicitly instantiate the int specialization in foo.cc, because we believe everyone and their dog will want the int specialization, and we want to save compile time:

// foo.cc
#include "foo-tmpl.h"

template <int> foo(int);

And compile:

$ c++ -std=c++11 -c a.cc
$ c++ -std=c++11 -c foo.cc
$ c++ a.o foo.o
$ ./a.out
42

Success!

Ok, but what about implicitly instantiating templates? We don't want to give up this unique power of templates. We can do it. This is why I put the implementation of foo in foo-tmpl.h instead of foo.cc. When we need to instantiate, we include the -tmpl.h instead of the .h. We should try to avoid doing this in other headers, and prefer to do it (once) in an implementation file. To demonstrate let's introduce a new function bar:

// bar.h
#pragma once

void bar();

And its implementation:

// bar.cc
#include "bar.h"
#include "foo-tmpl.h"

void bar()
{
    foo("bar");
}

Now we are implicitly instantiating void foo<const char*>(const char*), but that's ok because we included foo-tmpl.h. Now we can use bar:

// b.cc
#include "bar.h"

int main(void) {
    bar();
    return 0;
}

Compile and run:

$ c++ -std=c++11 -c b.cc
$ c++ -std=c++11 -c bar.cc
$ c++ b.o bar.o
$ ./a.out
bar

And finally, let's use them together

// c.cc
#include "foo.h"
#include "bar.h"

int main(void) {
    foo(42);
    bar();
    return 0;
}

Compile and run:

$ c++ -std=c++11 -c c.cc
$ c++ c.o foo.o bar.o
$ ./a.out 
42
bar

Just to make sure we understand what's going on under the covers, let's look at the symbols with nm, and make sure things are defined where we expect them to be:

$ nm *.o | c++filt  # manually-filtered output follows
a.o:
                 U void foo<int>(int)

b.o:
                 U bar()

c.o:
                 U bar()
                 U void foo<int>(int)

foo.o:
0000000000000000 T void foo<int>(int)

bar.o:
0000000000000000 T bar()
0000000000000075 S void foo<char const*>(char const*)

I performed these explorations with gcc 4.8.


$ c++ --version
c++ (MacPorts gcc48 4.8-20130210_0) 4.8.0 20130210 (experimental)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

With C++11 you also have extern template at your disposal, which lets you avoid implicit instantiation. So if you have many files which instantiate the MyClass specialization, and don't want foo.cc to even be aware of MyClass, you can add this to MyClass.h:

// MyClass.h
#include "foo.h"
class MyClass {
    //...
};

extern template void foo<MyClass>(MyClass);

And then MyClass.cc looks something like this:

// MyClass.cc
#include "MyClass.h"
#include "foo-tmpl.h"

// explicitly instantiate templates
template void foo<MyClass>(MyClass);

MyClass::MyClass() {
    // ...
}

// ...

Now the MyClass instantiation of foo will only be compiled once in MyClass.cc, but can be used in umpteen other files.

26Mar/0818

QCad on Leopard

I finally got around to building QCad on OS X Leopard. There are two main hurdles: getting Qt3 to build and getting QCad to build.

At first I tried building Qt3 with macports, but building QCad was a royal pain with the X11 version of Qt3 on OS X, for whatever reason. So I tried to install the qt3-mac MacPorts package, but that failed. So I was on my own building Qt3.

This patch will allow Qt3 to build on Leopard, by following the instructions in the INSTALL file. Here's the diffstat:

 config.tests/mac/mac_version.test |    2 +-
 src/kernel/qcursor_mac.cpp        |    4 ++++
 src/kernel/qt_mac.h               |    2 +-
 src/tools/qglobal.h               |    5 ++++-
 4 files changed, 10 insertions(+), 3 deletions(-)

I put it in /Developer/qt3, and I wrote a script to source on demand rather
than setting QTDIR and friends in my .profile or .bashrc, since I more
often want Qt4 than Qt3. I configure with -static, so applications like QCad
are built with Qt3 statically, which just makes things work better.

QCad needs a patch as well:

Index: qcad-2.0.5.0-1-community.src/mkspecs/defs.pro
===================================================================
--- qcad-2.0.5.0-1-community.src.orig/mkspecs/defs.pro  2008-03-26 08:46:25.000000000 -0600
+++ qcad-2.0.5.0-1-community.src/mkspecs/defs.pro       2008-03-26 08:46:48.000000000 -0600
@@ -1,6 +1,6 @@
 # $Id: defs.pro 606 2004-12-25 03:08:40Z andrew $
-QMAKE_CXXFLAGS_DEBUG += -pedantic
-QMAKE_CXXFLAGS += -pedantic
+#QMAKE_CXXFLAGS_DEBUG += -pedantic
+#QMAKE_CXXFLAGS += -pedantic

 win32 {
   QMAKE_CFLAGS_THREAD -= -mthreads
Index: qcad-2.0.5.0-1-community.src/scripts/build_qcad.sh
===================================================================
--- qcad-2.0.5.0-1-community.src.orig/scripts/build_qcad.sh     2008-03-26 08:46:06.000000000 -0600
+++ qcad-2.0.5.0-1-community.src/scripts/build_qcad.sh  2008-03-26 08:46:49.000000000 -0600
@@ -30,7 +30,7 @@ then
     export MAKE=gmake
     echo "Platform is Solaris"
     platform=solaris
-elif [ "x$OSTYPE" == "xdarwin8.0" ]
+elif [ "x$OSTYPE" == "xdarwin8.0" -o "x$OSTYPE" == "xdarwin9.0" ]
 then
     export MAKE=make
     echo "Platform is Mac OS X"

Then do

cd scripts
./build_qcad.sh notrans

It will complain about not finding qm/*.qm, but that's a nonfatal error.
QCad.app will be in the qcad directory, ready for your use.

I built this on an Intel MacBook running Leopard. If you think that matches
your setup, you're free to download my QCad.app and avoid
building both Qt3 and QCad.

Tagged as: , , , , 18 Comments
20Mar/08Off

Watch Movie Online Get Out (2017) subtitle english

Poster Movie Get Out 2017

Get Out (2017) HD

Director : Jordan Peele.
Producer : Edward H. Hamm Jr. , Sean McKittrick, Jason Blum.
Release : February 24, 2017
Country : United States of America.
Production Company : Blumhouse Productions, QC Entertainment.
Language : English.
Runtime : 103 min.
Genre : Comedy, Horror, Mystery, Thriller.

Movie 'Get Out' was released in February 24, 2017 in genre Comedy. Jordan Peele was directed this movie and starring by Daniel Kaluuya. This movie tell story about A young black man visits his white girlfriend's cursed family estate. He finds out that many of its residents, who are black, have gone missing in the past.

Do not miss to Watch movie Get Out (2017) Online for free with your family. only 2 step you can Watch or download this movie with high quality video. Come and join us! because very much movie can you watch free streaming.

Watch movie online Get Out (2017)
Incoming search term :

Watch Get Out 2017 Online Free
Get Out 2017 English Episodes
Watch Get Out 2017 Online Megashare
trailer movie Get Out 2017
Get Out 2017 Full Episode
Get Out 2017 Full Episodes Online
streaming movie Get Out 2017
Get Out 2017 For Free online
watch full film Get Out 2017
Watch Get Out 2017 Online Putlocker
watch Get Out 2017 film now
Get Out 2017 English Episodes Free Watch Online
Get Out 2017 live streaming film online
Get Out 2017 film trailer
watch full film Get Out 2017 online
Get Out 2017 English Full Episodes Free Download
Get Out 2017 English Full Episodes Download
film Get Out 2017 online streaming
Watch Get Out 2017 Online Viooz
Get Out 2017 movie streaming
Get Out live streaming film
Get Out 2017 Episodes Watch Online
Get Out 2017 English Full Episodes Online Free Download
Watch Get Out 2017 Online Free putlocker
Get Out 2017 Watch Online
watch full Get Out movie online
Watch Get Out 2017 Online Free megashare
movie Get Out 2017 streaming
download movie Get Out now
watch full movie Get Out 2017 online
Get Out 2017 Online Free Megashare
download Get Out movie now
Get Out 2017 English Episode
download full movie Get Out 2017
Get Out 2017 Episodes Online
Get Out 2017 For Free Online
Get Out 2017 Full Episodes Watch Online
Get Out 2017 HD English Full Episodes Download
Watch Get Out 2017 Online Free Viooz
download film Get Out 2017 now
Get Out 2017 HD Full Episodes Online
Get Out 2017 English Full Episodes Watch Online
Get Out 2017 streaming
Watch Get Out 2017 Online Free Putlocker