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?

Gulshan
  • 9,402
  • 10
  • 58
  • 89
  • 19
    Nope. C++ templates are compiled. – Edward Strange Mar 01 '11 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? – James McNellis Apr 15 '11 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- http://en.wikipedia.org/wiki/Preprocessor#Lexical_preprocessors – Gulshan Apr 15 '11 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. – James McNellis Apr 15 '11 at 17:54
  • 1
    The template language is actually turing complete so they are much more than enhanced macros. –  Apr 19 '11 at 21:46
  • I got my answer from- http://en.wikipedia.org/wiki/Template_(programming)#Advantages_and_disadvantages – Gulshan Apr 26 '11 at 10:29
  • Isn't every statement a kind of glorified macro? `a += b;` is just a glorified macro for `add a, b` which is just a glorified macro for `add ebx, dword ptr [ebp-8]` which is just a glorified macro for some bytes I can't be bothered to look up. – user253751 Apr 21 '17 at 02:17

5 Answers5

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.

David Thornley
  • 20,238
  • 2
  • 55
  • 82
  • 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). – Martin York Mar 01 '11 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 ? – Matthieu M. Apr 15 '11 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. – Martin York Apr 15 '11 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. – David Thornley Apr 18 '11 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. – Matthieu M. Apr 18 '11 at 14:19
  • @LokiAstari That sounds useful, could you point us to a code example? – Dan Jun 09 '14 at 12:55
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.

SK-logic
  • 8,497
  • 4
  • 25
  • 37
  • 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 '11 at 20:26
  • @quant_dev, C++ templates can't use anything defined within the rest of C++. For example, template can't parse its string argument into an AST and compile the result somehow. In Lisp you can do it - macros can call any of the previously defined Lisp functions and refer to the global variables. – SK-logic Apr 20 '11 at 09:44
  • 2
    Uhm, actually... https://github.com/kmichel/bf0x – Cactus Golov Jan 15 '12 at 12:07
  • @AntonGolov, that's C++11 – SK-logic Jan 15 '12 at 12:35
  • 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 '12 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 '12 at 17:26
  • @SK-logic: Apologies. I didn’t take note of the date. The distinction between compiletime and runtime is unfortunate, but remove it and you’d have dependently typed C++. I’m not sure the world needs that particular monstrosity. – Jon Purdy Jan 15 '12 at 17:51
  • @Jon Purdy, first class macros are orthogonal to the type system. It is perfectly possible to implement C++ with a Lisp-like macro subsystem. – SK-logic Jan 15 '12 at 18:26
  • @SK-logic: Well, yes. All I’m saying is that because templates specifically are part of the type system, you naturally can’t statically type a template that depends on runtime values. Allowing runtime templates would give C++ a dependent type system, which is simultaneously intriguing and horrifying. – Jon Purdy Jan 15 '12 at 22:29
  • 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: http://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 '13 at 16:55
  • 1
    Scheme starting with R5RS switched from full Lisp-style macros to the "hygienic" macros that are _weaker_ than full Lisp-style macros. I suspect they are so much weaker they are actually even weaker than C++ templates. – Jan Hudec Aug 26 '14 at 13:06
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.

Martin Beckett
  • 15,776
  • 3
  • 42
  • 69
  • I haven't said about C++ being a glorified macro. I admire C++ a lot. Just being curious. – Gulshan Mar 01 '11 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. – David Thornley Mar 01 '11 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 '12 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 '12 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.

Simon Richter
  • 1,568
  • 9
  • 10
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.

Marc
  • 339
  • 1
  • 8