Y
Yang Zhang
I have a small program like this:
////////////////////////////////////////////////
#include <iostream>
using namespace std ;
// set bits in an address
template <typename T>
inline T*
set_addr(const T* addr, unsigned long n) {
return (T*)( (unsigned long)addr | n) ;
}
// helper class that clears the last two bits of an address
template <typename T, int S>
struct clear_addr_helper {} ;
// 32 bit pointer specialization
template <typename T>
struct clear_addr_helper<T,4> {
static inline T*
clear(const T* addr) {
return (T*)( (unsigned long)addr & 0xfffffffc) ;
}
} ;
// 64 bit pointer specialization
template <typename T>
struct clear_addr_helper<T,8> {
static inline T*
clear(const T* addr) {
return (T*)( (unsigned long)addr & 0xfffffffffffffffc) ;
}
// a function that won't compile
static inline void
error() { ss }
} ;
template <typename T>
inline T*
clear_addr(const T* addr) {
return clear_addr_helper<T,sizeof(T*)>::clear(addr) ;
}
int
main() {
short* p = new short(1) ;
cout << "sizeof(short*): " << sizeof(short*) << endl ;
cout << "p = " << p << endl ;
cout << "set_addr(p,0x1): " << set_addr(p,0x1) << endl ;
cout << "clear_addr(set_addr(p,0x2)): "
<< clear_addr(set_addr(p,0x2)) << endl ;
}
////////////////////////////////////////////////
g++ (version 4.0.1) won't compile this program on a 32 bit machine. It
complained the 64 bit specialization: the "0xfffffffffffffffc" in the
"clear" method is too large, and the "error" method is in error. But
since on a 32 bit machine, only the 32 bit pointer template
specialization is needed. It seems that g++ has looked both of them.
Other compilers such as the Intel/Sun Workshop/SGI C++ compilers all
compiled the above code without problem. I think they all didn't look at
the 64 bit pointer template specialization.
Is this behavior implementation dependent? Is there a way (a
command-line option) to make g++ behave like others?? Or I cannot assume
a lazy instantiation for the compiler?
Thanks in advance,
--Yang
////////////////////////////////////////////////
#include <iostream>
using namespace std ;
// set bits in an address
template <typename T>
inline T*
set_addr(const T* addr, unsigned long n) {
return (T*)( (unsigned long)addr | n) ;
}
// helper class that clears the last two bits of an address
template <typename T, int S>
struct clear_addr_helper {} ;
// 32 bit pointer specialization
template <typename T>
struct clear_addr_helper<T,4> {
static inline T*
clear(const T* addr) {
return (T*)( (unsigned long)addr & 0xfffffffc) ;
}
} ;
// 64 bit pointer specialization
template <typename T>
struct clear_addr_helper<T,8> {
static inline T*
clear(const T* addr) {
return (T*)( (unsigned long)addr & 0xfffffffffffffffc) ;
}
// a function that won't compile
static inline void
error() { ss }
} ;
template <typename T>
inline T*
clear_addr(const T* addr) {
return clear_addr_helper<T,sizeof(T*)>::clear(addr) ;
}
int
main() {
short* p = new short(1) ;
cout << "sizeof(short*): " << sizeof(short*) << endl ;
cout << "p = " << p << endl ;
cout << "set_addr(p,0x1): " << set_addr(p,0x1) << endl ;
cout << "clear_addr(set_addr(p,0x2)): "
<< clear_addr(set_addr(p,0x2)) << endl ;
}
////////////////////////////////////////////////
g++ (version 4.0.1) won't compile this program on a 32 bit machine. It
complained the 64 bit specialization: the "0xfffffffffffffffc" in the
"clear" method is too large, and the "error" method is in error. But
since on a 32 bit machine, only the 32 bit pointer template
specialization is needed. It seems that g++ has looked both of them.
Other compilers such as the Intel/Sun Workshop/SGI C++ compilers all
compiled the above code without problem. I think they all didn't look at
the 64 bit pointer template specialization.
Is this behavior implementation dependent? Is there a way (a
command-line option) to make g++ behave like others?? Or I cannot assume
a lazy instantiation for the compiler?
Thanks in advance,
--Yang