简体   繁体   中英

How to convert a 32 bit signed integer value to 64 bit signed integer equivalent in C

I have a library that is compiled to use 32 bit signed integer. When other applications compile theirs with a flag eg: -DODBC64 it promotes the same type I have used in my library to a 64 bit signed integer. eg:

 #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. eg:

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.

Your library can't access the upper 4 bytes, but you can before you call it. So try to initialize it with 0's first:

SLEN count = 0; // initialize with 0's
mylibraryfunction(&count);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM