C++ Templates And C++ Preprocessor

Oct 7, 2010 at 5:07pm
I thought I might be able to see how class templates actually expand by using the /E or /P command line switches with the Microsoft cl compiler and compiling on the command line but it doesn't seem to be working. Does anyone know if this can be done or a way to do it? Perhaps there is no way to do it although I thought the preprocessor expanded templates. Anyway here is a little program with a template in it, my command line attempt right after it, and the slightly abreviated output that just shows about the exact same program at bottom with the template still in place...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>  //Templ9

class CBase
{
 public:
 CBase()  {puts("Called CBase Constructor!");}
 virtual ~CBase() {puts("Called CBase Destructor!");}
 void BaseMethod() {puts("Called BaseMethod() In CBase!");}
};

class CMath : public CBase
{
 public:
 CMath()  {puts("Called CMath Constructor!");}
 ~CMath() {puts("Called CMath Destructor!");}
 void BaseMethod() {puts("Called BaseMethod() In CMath!");}
};

template <class T> class CComObject : public T
{
 public:
 CComObject(){}
 ~CComObject(){}

 void CallBaseMethod()
 {
  T* pT=static_cast<T*>(this);
  pT->BaseMethod();
 }
};

int main()
{
 CComObject<CMath>* pMath;

 pMath=new CComObject<CMath>;
 pMath->CallBaseMethod();
 getchar();

 return 0;
}


Here was my command line with VC6...

C:\Code\VStudio\VC++6\Projects\ATL\Armstrong\ch1\templ9>cl Main.cpp /E

And here's the output...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#line 243 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"
#line 244 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"
#line 247 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

 int __cdecl _filbuf(FILE *);
 int __cdecl _flsbuf(int, FILE *);

 FILE * __cdecl _fsopen(const char *, const char *, int);
#line 283 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

 void __cdecl clearerr(FILE *);
 int __cdecl fclose(FILE *);
 int __cdecl _fcloseall(void);

 FILE * __cdecl _fdopen(int, const char *);
#line 293 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

 int __cdecl feof(FILE *);
 int __cdecl ferror(FILE *);
 int __cdecl fflush(FILE *);
 int __cdecl fgetc(FILE *);
 int __cdecl _fgetchar(void);
 int __cdecl fgetpos(FILE *, fpos_t *);
 char * __cdecl fgets(char *, int, FILE *);

 int __cdecl _fileno(FILE *);
#line 307 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

 int __cdecl _flushall(void);
 FILE * __cdecl fopen(const char *, const char *);
 int __cdecl fprintf(FILE *, const char *, ...);
 int __cdecl fputc(int, FILE *);
 int __cdecl _fputchar(int);
 int __cdecl fputs(const char *, FILE *);
 size_t __cdecl fread(void *, size_t, size_t, FILE *);
 FILE * __cdecl freopen(const char *, const char *, FILE *);
 int __cdecl fscanf(FILE *, const char *, ...);
 int __cdecl fsetpos(FILE *, const fpos_t *);
 int __cdecl fseek(FILE *, long, int);
 long __cdecl ftell(FILE *);
 size_t __cdecl fwrite(const void *, size_t, size_t, FILE *);
 int __cdecl getc(FILE *);
 int __cdecl getchar(void);
 int __cdecl _getmaxstdio(void);
 char * __cdecl gets(char *);
 int __cdecl _getw(FILE *);
 void __cdecl perror(const char *);
 int __cdecl _pclose(FILE *);
 FILE * __cdecl _popen(const char *, const char *);
 int __cdecl printf(const char *, ...);
 int __cdecl putc(int, FILE *);
 int __cdecl putchar(int);
 int __cdecl puts(const char *);
 int __cdecl _putw(int, FILE *);
 int __cdecl remove(const char *);
 int __cdecl rename(const char *, const char *);
 void __cdecl rewind(FILE *);
 int __cdecl _rmtmp(void);
 int __cdecl scanf(const char *, ...);
 void __cdecl setbuf(FILE *, char *);
 int __cdecl _setmaxstdio(int);
 int __cdecl setvbuf(FILE *, char *, int, size_t);
 int __cdecl _snprintf(char *, size_t, const char *, ...);
 int __cdecl sprintf(char *, const char *, ...);
 int __cdecl sscanf(const char *, const char *, ...);
 char * __cdecl _tempnam(const char *, const char *);
 FILE * __cdecl tmpfile(void);
 char * __cdecl tmpnam(char *);
 int __cdecl ungetc(int, FILE *);
 int __cdecl _unlink(const char *);
 int __cdecl vfprintf(FILE *, const char *, va_list);
 int __cdecl vprintf(const char *, va_list);
 int __cdecl _vsnprintf(char *, size_t, const char *, va_list);
 int __cdecl vsprintf(char *, const char *, va_list);

#line 363 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

 FILE * __cdecl _wfsopen(const wchar_t *, const wchar_t *, int);
#line 369 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

 wint_t __cdecl fgetwc(FILE *);
 wint_t __cdecl _fgetwchar(void);
 wint_t __cdecl fputwc(wint_t, FILE *);
 wint_t __cdecl _fputwchar(wint_t);
 wint_t __cdecl getwc(FILE *);
 wint_t __cdecl getwchar(void);
 wint_t __cdecl putwc(wint_t, FILE *);
 wint_t __cdecl putwchar(wint_t);
 wint_t __cdecl ungetwc(wint_t, FILE *);

 wchar_t * __cdecl fgetws(wchar_t *, int, FILE *);
 int __cdecl fputws(const wchar_t *, FILE *);
 wchar_t * __cdecl _getws(wchar_t *);
 int __cdecl _putws(const wchar_t *);

 int __cdecl fwprintf(FILE *, const wchar_t *, ...);
 int __cdecl wprintf(const wchar_t *, ...);
 int __cdecl _snwprintf(wchar_t *, size_t, const wchar_t *, ...);
 int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
 int __cdecl vfwprintf(FILE *, const wchar_t *, va_list);
 int __cdecl vwprintf(const wchar_t *, va_list);
 int __cdecl _vsnwprintf(wchar_t *, size_t, const wchar_t *, va_list);
 int __cdecl vswprintf(wchar_t *, const wchar_t *, va_list);
 int __cdecl fwscanf(FILE *, const wchar_t *, ...);
 int __cdecl swscanf(const wchar_t *, const wchar_t *, ...);
 int __cdecl wscanf(const wchar_t *, ...);

 FILE * __cdecl _wfdopen(int, const wchar_t *);
 FILE * __cdecl _wfopen(const wchar_t *, const wchar_t *);
 FILE * __cdecl _wfreopen(const wchar_t *, const wchar_t *, FILE *);
 void __cdecl _wperror(const wchar_t *);
 FILE * __cdecl _wpopen(const wchar_t *, const wchar_t *);
 int __cdecl _wremove(const wchar_t *);
 wchar_t * __cdecl _wtempnam(const wchar_t *, const wchar_t *);
 wchar_t * __cdecl _wtmpnam(wchar_t *);

#line 414 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"
#line 415 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"
#line 418 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

 int __cdecl fcloseall(void);
 FILE * __cdecl fdopen(int, const char *);
 int __cdecl fgetchar(void);
 int __cdecl fileno(FILE *);
 int __cdecl flushall(void);
 int __cdecl fputchar(int);
 int __cdecl getw(FILE *);
 int __cdecl putw(int, FILE *);
 int __cdecl rmtmp(void);
 char * __cdecl tempnam(const char *, const char *);
 int __cdecl unlink(const char *);

#line 463 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"
}
#line 467 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

#pragma pack(pop)
#line 471 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"

#line 473 "C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\stdio.h"
#line 2 "Main.cpp"

class CBase
{
 public:
 CBase()  {puts("Called CBase Constructor!");}
 virtual ~CBase() {puts("Called CBase Destructor!");}
 void BaseMethod() {puts("Called BaseMethod() In CBase!");}
};

class CMath : public CBase
{
 public:
 CMath()  {puts("Called CMath Constructor!");}
 ~CMath() {puts("Called CMath Destructor!");}
 void BaseMethod() {puts("Called BaseMethod() In CMath!");}
};

template <class T> class CComObject : public T
{
 public:
 CComObject(){}
 ~CComObject(){}

 void CallBaseMethod()
 {
  T* pT=static_cast<T*>(this);
  pT->BaseMethod();
 }
};

int main()
{
 CComObject<CMath>* pMath;

 pMath=new CComObject<CMath>;
 pMath->CallBaseMethod();
 (--((&_iob[0]))->_cnt >= 0 ? 0xff & *((&_iob[0]))->_ptr++ : _filbuf((&_iob[0])));

 return 0;
}
Oct 7, 2010 at 5:33pm
The preprocessor doesn't "expand" templates. It is done later in the compiling process. But it isn't textually visible like preprocessors.
Last edited on Oct 7, 2010 at 5:33pm
Oct 7, 2010 at 6:59pm
Thanks R0mai for the info. That's about what I figured. I thought it would be neat though to see it! It was worth a try!
Topic archived. No new replies allowed.