I have a library that is compiled to use 32 bit signed integer. When other applications compile theirs with a flag e.g: -DODBC64 it promotes the same type I have used in my library to a 64 bit signed integer. e.g:
#ifdef ODBC64
typedef sint64 SLEN;
#else
#define SLEN int
#endif
When the application passes reference to my library as :
SLEN count;
mylibraryfunction(&count);
the values returned to application looks like these:
sizeof(SLEN) = 8
sizeof(SLEN) in my library = 4
m_AffectedRows BEFORE = 0x3030303030303030
m_AffectedRows AFTER = 0x3030303000000000 0
You can see that the assignment from my lib is copying 4 bytes (value 0). I need to know a way to reset the upper 4 bytes to 0. e.g:
0x0000000000000000
I have tried both static_cast and reinterpret_cast, but none are helpful.
I made a MCVE where I resembled what happens in OPs case.
I even didn't need an extra library for this, just two translation units (resulting in two object files).
First lib.cc
:
#include <cstdint>
extern "C" void func(int32_t *pValue);
void func(std::int32_t *pValue)
{
*pValue = 0;
}
Second prog.cc
:
#include <iostream>
#include <iomanip>
// how prog.cc "knows" func():
extern "C" void func(int64_t *pValue);
int main()
{
int64_t value = 0x0123456789ABCDEFull;
std::cout << "value before: " << std::hex << value << '\n';
func(&value);
std::cout << "value after : " << std::hex << value << '\n';
return 0;
}
Compiler errors? No. Each translation unit uses prototype of func()
conformant.
Linker errors? No. The symbols match, anything else is beyond view of linker.
I must admit I had to use extern "C"
to achieve this. Otherwise, at least, the C++ name mangling had prevented the proper linking. (When I became aware of this, I made code in C.)
Output:
value before: 123456789abcdef
value after : 123456700000000
Live Demo on wandbox
This is very dangerous! Any use of any extern symbol should use a 100 % compatible declaration. (And yes, C and C++ provide various ways to shoot into your own foot.)
Imagine what would happen if the lib.cc function func()
would write int64_t
where the prog.cc would pass a pointer to int32_t
: Out of bound access with possible more disastrous consequences.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With