30

From different comparisons among C++ templates and C#/Java generics like this one-

https://stackoverflow.com/questions/31693/what-are-the-differences-between-generics-in-c-and-java-and-templates-in-c/31929#31929

I got a perception that, C++ templates are implemented by some kind of preprocessing(plain text replacement prior to parsing), not compiling. Because the type checking in C++ templates resembles C macros. I mean, if there are some errors, they are errors from the generated code after processing templated code blocks, not from the templates themselves. In other words, they are just a kind of upper version of macros in C.

Then I found some other facts supporting this-

  • I thought, if C++ templates are implemented by preprocessing, there will be issues with dynamic linking(using .dll). And a quick googling supported this.

  • Another point is, integer constants can be passed as arguments to the templates. And it even supports some kind of recursion. But this recursion is not found in the compiled assembly/machine code. The recursion thing is managed in compile time by generating a functions for every recursive call and thus having a larger but faster executable binary.

Though unlike C macros, it has some superior abilities. But isn't C++ template implemented with some kind of preprocessing? How is this implemented in different C++ compilers?

7
  • 19
    Nope. C++ templates are compiled. Mar 1, 2011 at 18:13
  • 2
    What is your definition of "preprocessing"? And of "compiling"? A sufficiently broad definition of "preprocessing" could include everything that a compiler does; after all, a compiler really just processes the source before it gets executed, no? Apr 15, 2011 at 17:20
  • @James McNellis IMHO if you can just differentiate preprocessing from all other things done for compilation, it is enough to understand my question. For clarifying preprocessor- en.wikipedia.org/wiki/Preprocessor#Lexical_preprocessors
    – Gulshan
    Apr 15, 2011 at 17:30
  • 6
    If you are referring to that form of preprocessing, then no, C++ templates are absolutely not just some sort of glorified macro. Apr 15, 2011 at 17:54
  • 1
    The template language is actually turing complete so they are much more than enhanced macros.
    – user7146
    Apr 19, 2011 at 21:46

5 Answers 5

13

C++ templates are a sort of dumbed down Lisp (or even more, Scheme) macros. It is a Turing-complete language which evaluates in compilation time, but it is severely limited as there is no access from that language to the underlying C++ environment. So, yes, C++ templates can be seen as some form of preprocessing, with a very limited interaction with the code being generated.

11
  • 3
    "but it is severely limited as there is no access from that language to the underlying C++ environment." -- What does it mean? I tried to parse this statement, but failed.
    – quant_dev
    Apr 19, 2011 at 20:26
  • 2
    Uhm, actually... github.com/kmichel/bf0x Jan 15, 2012 at 12:07
  • 3
    @SK-logic: As an aside, C++11 is C++, unless you (pedantically) treat different versions of the same language as different languages.
    – Jon Purdy
    Jan 15, 2012 at 17:03
  • 3
    @Jon Purdy, C++11 did not exist (officially) by the time of this answer. Nowadays an example would have been more complicated, like decomposing a data structure, using a library function, etc.
    – SK-logic
    Jan 15, 2012 at 17:26
  • 1
    @SK-logic: Do you happen to know implementation of C++ with a Lisp-like macros? I'm getting sick of template limitations. An example of C++-style syntax language with powerful macro system in Haxe: haxe.org/manual/macros . (Doesn't help me because I use C++ to its purpose - programming 8-bit microcontrollers; there're better languages for anything else).
    – pfalcon
    Apr 13, 2013 at 16:55
43

Probably the biggest difference is that C macros are expanded in the preprocessing phase, before any other compiling is done, while C++ templates are part of compilation. This means that C++ templates are type-aware and scoped, among other things, and are not simple textual substitution. They can compile to real functions, and therefore avoid most of the problems macros have. Being type-aware means that they can be general or specialized: for example, it's easy to provide a swap template function, and easy to write specializations that work well even if the objects manage heap memory.

Therefore: C++ templates are not preprocessing in the same sense macros are, they are not a kind of C macro, and it is impossible to use C macros to duplicate what templates do.

Templates live in header files, not in linked libraries, true, but if you're supplying a .dll you're presumably also supplying a header file for it to use.

6
  • 12
    They do not need to live in the header file (that is just the simplest technique to using them). You can define them in a source file and manually force instantiation of the template in the source file (compilation unit). Linking will then pick up the instantiations as normal (this is a technique for limiting templates to specific types and not allowing all generic types). Mar 1, 2011 at 19:06
  • @Martin: I am not sure if this technic (while supported) is actually explicitly supported by the standard. Otherwise all compilers would have export implemented already. I know it kind of works for functions, but I doubt it works for classes: how would you know their size ? Apr 15, 2011 at 18:26
  • @Matthieu M: This has nothing to do with the export keyword. It deals with "Explicit" template instantiation and is well defined in the standard. Apr 15, 2011 at 23:15
  • 2
    @Matthieu M.: If the compiler knows the signature of a function, and the linker can find an implementation, everything's cool. That applies whether or not the function is a template function. In practice, they generally live in header files, because forcing specific instantiations is typically more work than it's worth, but Martin is correct in noting the alternative. Apr 18, 2011 at 13:53
  • I know it works, for sure, for specialized functions. However I am also quite sure, that it does not work for classes, which was my point. I think it works for methods from specialized classes too, but do not know whether or not this is standard. Apr 18, 2011 at 14:19
6

Does it matter how they are implemented? The early C++ compilers were just pre-processors that fed the code to a c compiler, it doesn't mean C++ is just a glorified macro.

Templates remove the need for a macros by providing a safer, more efficient and specializable (even I don't think thats a real word) way of implementing code for multiple types.

There are a variety of ways to do templating type code in c, none of which are very nice once you get beyond simple types.

4
  • I haven't said about C++ being a glorified macro. I admire C++ a lot. Just being curious.
    – Gulshan
    Mar 1, 2011 at 17:46
  • 2
    @Gulshan: No, you didn't say anything about that. Nevertheless, that's how early C++ compilers worked (except that CFront was something of a compiler instead of just a macro preprocessor), and your statements about C++ templates are about as applicable to early C++ itself. Mar 1, 2011 at 17:53
  • CFront compiled C++ to C. The line between preprocessor and compiler is clearly defined: a compiler attempts to understand its input—via parsing, AST building, &c.—while a preprocessor does not—e.g., using only textual or token substitution.
    – Jon Purdy
    Jan 15, 2012 at 17:06
  • 2
    I think what David meant is that there is an underlying subset of C++ and that templates can be thought of as some kind of macros that are used to general a program in this subset, which can then be compiled as a further, separate stage.
    – Giorgio
    Jul 13, 2012 at 18:59
5

There are some differences; for example, templates can be used to instantiate a function overload when needed, while with macros, you'd have to expand the macro once for each possible overload in order to make it visible to the compiler, so you'd end up with lots of unused code.

Another difference is that templates honour namespaces.

2

IMHO, C++ templates and C Macros were meant to solve two entirely different problems. The original C++ Standard Template Library was a mechanism to cleanly decouple container classes (arrays, linked-lists, etc.) from the generic functions commonly applied to them (like sorting and concatenation). Having abstract representations of efficient algorithms and data structures lead to more expressive code because there was significantly less guesswork in how to best to implement a function working on a particular piece of data. The C macros were much more in line with what one would typically see in Lisp macros, in that they provided a means to "extend" the language with inlined code. The cool thing is that the C++ Standard Library extended the functionality of templates to cover the vast majority off what we use #define for in C.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.