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]
# 1
Hello.Could you provide complete compilable test case? From your example it isn't clear where is a declaration of class 'foo' etc.
Atanasyan at 2007-7-6 22:10:37 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 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

sjgilbertz at 2007-7-6 22:10:37 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 3
The simpliest workaround is to include foo.cpp into foo.h and switch off searching for template definition by -template=no%extdef.It looks like a compiler bug. Please, submit bug report here http://bugs.sun.com/services/bugreport/index.jsp.
Atanasyan at 2007-7-6 22:10:37 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 4
Explicit inclusion at the top would certainly solve the problem, but since our product is mostly templates calling each other it would make the build time unacceptable.I'll report it as a bug and see what happens.Thanks-- Steve
sjgilbertz at 2007-7-6 22:10:37 > top of Java-index,Development Tools,Solaris and Linux Development Tools...