Problems with #define bleeding into templates
Hello again,
I got into a real problem thanks to the way template instantiation across multiple files is now handled.
In foo.cpp:
[code]
...
template<class SKT> foo<SKT>::setLak() {...}
...
[/code]
in File1.cpp
[code]
...
#define SKT int64_t
...
foo<int32_t> myfoo;
...
[/code]
in File2.cpp:
[code]
int main()
{
foo<int32_t> myfoo;
myfoo.setLak();
...
[/code]
sun02% CC -V
CC: Sun C++ 5.8 Patch 121017-02 2006/04/19
When the template was instantiated in File1.cpp it was with SKTYPE defined as int64_t. This lead to an extremely subtle bug which caused code in File2.cpp to show symptoms of memory corruption at runtime, even though File2.cpp and the template were both correct, and nothing else had been executed.
Is there any way of restricting how much context gets into a template instantiation to prevent a third party from corrupting a template at compile-time in this way?
Thanks
-- Steve
[1101 byte] By [
sjgilbertz] at [2007-11-26 8:37:45]

# 2
Hello again
Here is a working example:
The template:
sun02% cat foo.h
template<class SKT> void sayit(SKT val);
sun02% cat foo.cpp
#include <stdio.h>
#include <inttypes.h>
template<class SKT> void sayit(SKT val)
{
printf("%lld\n", (int64_t) val);
}
sun02%
The function which sabotages the template:
sun02% cat file1.cpp
#include <inttypes.h>
#include "foo.h"
void never_called()
{
#define SKT int64_t
sayit<int32_t>(3);
}
sun02%
The file which uses the template:
sun02% cat file2.cpp
#include <inttypes.h>
#include "foo.h"
int main()
{
sayit<int32_t>(3);
}
sun02%
And the result:
sun02% CC -o main file1.cpp file2.cpp
file1.cpp:
file2.cpp:
sun02% main
15025300952
sun02% CC -V
CC: Sun C++ 5.8 Patch 121017-02 2006/04/19
sun02%
-
The bad #define turns the template into:
template<class int64_t> void sayit(int64_t)
{
printf("%lld\n", (int64_t) val);
}
Then the compiler treats 'int64_t' as a template parameter and instantiates the template as
template<class int32_t> void sayit(int32_t)
{
printf("%lld\n", (int32_t) val);
}
and this is the instance selected by the linker when file1.o and file2.o are linked.
Thanks
-- Steve