Compiling gsoap for x64 with Visual Studio: C4302 conversion: truncation from void* to unsigned int - 64-bit

I am trying to compile gsoap with VS 2017 for x64. There's a compiler warning because void* (64bit address) is casted to unsigned int (32bit integer). It occurs at h = soap_hash_ptr(p) where p is the void* and h is the unsigned int.
That looks critical - I therefore had a look into stdsoap2.cpp of the current gsoap version - there however soap_hash_ptr seems to do the same through PtrToUlong - I want to keep gsoap which is great - but can I still rely on - possibly yes, because the return value of soap_hash_ptr is used as an index for an array or vector (either soap->mht or soap->pht) - however I am not yet quite shure - can someone give me a hint? Thank you.
IDE: VS2017
Target: x64
gsoap version: Approx year 2005

The PtrToUlong is correctly used to truncate the pointer, as this is actually recommended by the Win64 rules for using pointers https://learn.microsoft.com/en-us/windows/desktop/winprog64/rules-for-using-pointers
Use the PtrToLong or PtrToUlong function to truncate pointers.
If you must truncate a pointer to a 32-bit value, use the PtrToLong or
PtrToUlong function (defined in Basetsd.h). These functions disable
the pointer truncation warning for the duration of the call.
The soap_hash_ptr macro that you quote is used to compute an index into a hash table:
#if defined(WIN32) && !defined(UNDER_CE)
#define soap_hash_ptr(p) ((PtrToUlong(p) >> 3) & (SOAP_PTRHASH - 1))
#else
#define soap_hash_ptr(p) ((size_t)(((unsigned long)(p) >> 3) & (SOAP_PTRHASH-1)))
#endif
This definition and its use to index a table cannot cause an issues.

Related

How to create a very large (more than INT_MAX) character buffer?

I am dealing with very large files, frequently over 2GBs, and need to dump them into a buffer to be able to deal with them.
I create the buffer like this:
char* bigBuffer = nullptr;
...
bigBuffer = new char[3'000'000'000];
The line that allocates the memory shows the following warning when all warnings are enabled: C4310 cast truncates constant value
I tried explicitly telling the compiler this is not an int by changing the line to:
bigBuffer = new char[3'000'000'000ull];
but I'm still getting the same warning. Seems like it is casting it implicitly to an int no matter what.
How do I get the compiler to allow me to create this array in the way I want, or even larger if needed?
I am on the latest version of Visual Studio 2019.

What is the meaning of "Yes, Virginia, it had better be unsigned"?

In the linux source code version 3.18 (and previous), in the string.c file, in the function strncasecmp, the very first thing is:
/* Yes, Virginia, it had better be unsigned */
unsigned char c1, c2;
As can be seen here: http://lxr.free-electrons.com/source/lib/string.c
What is the meaning of this?
string.c:strncasecmp() calls __tolower from include/linux/ctype.h which expects an unsinged char.
EDITed to add: In general you always want to pass unsigned char to ctype.h functions because of C Standard ยง7.4, which says the behavior is undefined if the argument to ctype.h functions is not representable as unsigned char or EOF. So that probably explains the "Yes, Virginia" bit.
What is a bit more mysterious is that include/linux/ctype.h actually appears idiot-proof in this respect, because it does its own safety-minded cast in #define __ismask(x) (_ctype[(int)(unsigned char)(x)]). I'm not sure when the "Yes, Virginia" comment was added relative to this other line, but with the current version of include/linux/ctype.h it appears that string.c:strncasecmp() would work fine even with char for c1 and c2. I haven't really tried to change & test it that way though...
Also if you go back to Linux 2.0.40's ctype.h, the safety-minded cast ((int)(unsigned char)) is not there anymore. There's no "Virginia" comment either in 2.0.40's string.c, but there's not even a strncasecmp in it. It looks like both changes were made somewhere in between Linux 2.0 and 2.2, but I can't tell you more right now which came first, etc.

Spurious (?) warning about string constants using a macro in OpenCL

I use the following macro in my OpenCL kernel:
#define ided_printf(_format, ...) printf("(%u,%u,%u) " _format, get_global_id(0), get_group_id(0), get_local_id(0), __VA_ARGS__ )
and it works fine. However, when I compile it (I use AMD's APP OpenCL library on Win7), I get the following warning on each use of the macro:
argument of type "const __constant char *" is incompatible with parameter of type "__constant char *"
Why would I be getting that? After all, string literals are const's. And even if the OpenCL compiler doesn't make them const, why is the "(%u, %u, %u)" string const'ed while the other string (_format) is not consted?
I'm assuming this is a compiler bug; if it is, a workaround would be appreciated. Maybe some sort of cast?
Based on that AMD forum's post, it is a bug. And yes a cast will do it as suggested in the same post:
printf((__constant char *)"%d\n", i);

Can I use $urandom_range with time variables?

I wanted to know if I can simply write:
time time_var;
time_var = $urandom_range (10ms, 7ms);
I've tried using it directly, and there are no errors/warnings issued.
However, the returned value is not between 7-10ms.
I guess it's legal to use $urandom_range with time literals, since I didn't receive any errors. But, why can't I get a value in the proper range?
The IEEE Std (1800-2009) declares the arguments to $urandom_range to be of type int unsigned which is not the same as time. I don't think you can rely on the system function to behave predictably even if you are not getting errors or warnings from your simulator.
It is a compile error in VCS and a warning with Incisive.
Can you use something like this?
int unsigned del = $urandom_range(10, 7);
#(1ms * del);

string to integer type conversion if the string is taken from text box in visual c++ using visual studion n windows forms

i need the code to convert the string type data into integer type data if i have entered a numerical value in the text box.
i am using visual c++ windows forms and the visual studio
i am using visual c++ windows forms and the visual studio
If it's really Windows Forms (i.e. C++/CLI) it's just Int32::Parse or Int32::TryParse, just like in any other .NET language.
I think what he wanted was:
String^ numberS = "42";
int number;
number = Convert::ToInt32(numberS);
Assuming that you have the variable in a std::string instance, you can use streams to do it like this:
std::string str = "1";
std::istringstream iss;
iss.str(str);
int val = 0;
iss>>val;
As long as you can access the raw character data in the text box you can simply use atoi

Resources