What is std::strtoul for unicode - c++

I'm trying to convert this code to unicode
int fromHex(const supportlib::string_t &s)
{
return std::strtoul(s.c_str(), NULL, 16);
}
supportlib::string_t is typedefed to std::string or std::wstring depending on whether I want to compile with unicode or ASCII.
With most other types I could find a wide version but not for std::strtoul so what should I use instead? std::wstrtoul doesn't do the trick as with most other types.
I'm using MingW with gcc 4.8.1.
When I compile it in unicode mode, I get this error:
error: cannot convert 'const wchar_t*' to 'const char*' for argument '1' to 'long unsigned int strtoul(const char*, char**, int)'

In C99 at least, it's in wchar.h and prototyped like this:
unsigned long int wcstoul ( const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);

Related

g++ (MinGW) can not convert wchar_t* to unsigned short* with option -fshort-wchar

I am porting a C++ Project from VisalStudio to GCC/MinGw.
The original project uses the compiler flag /Zc:wchar_t-, which defines the type wchar_t as an unsigned short (should be 2 bytes).
Now when I compile with g++ and the option -fshort-wchar. According to the documentation this option should also define wchar_t as an unsigned short.
Now there is a function
void myfuncExample(short unsigned int*)
which is called with an wchar_t* variable, which should be castable to an unsigned short*.
However, when compiling I get this error:
error: invalid conversion from 'wchar_t*' to 'short unsigned int*' [-fpermissive]
myfuncExample(buf);
^~~
Why can it no be converted? If i remove the -fshort-wchar option, the error is the same. It seems like g++ is ignoring the option. Any advice?
-fshort-wchar sets sizeof(wchar_t) to 2 (which is already the default on Windows, unlike 4 elsewhere).
It doesn't make wchar_t the same type as unsigned short (even though they will have the same size and signedness).
You'll need to fix the code.

argument of type is incompatible with parameter of type error [duplicate]

This question already has answers here:
Cannot convert parameter from 'const char[20]' to 'LPCWSTR'
(3 answers)
'CreateDirectoryW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR' in OpenCV 2.4.5 and VS 2010
(3 answers)
cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}'
(4 answers)
'HMODULE LoadLibraryA(LPCSTR)': cannot convert argument 1 from 'const _Elem *' to 'LPCSTR'
(2 answers)
Cannot convert const char[16] to LPCWSTR [closed]
(1 answer)
Closed 1 year ago.
uintptr_t gameModule = (uintptr_t)GetModuleHandle("client.dll");
Severity Code Description Project File Line Suppression State
Error C2664 'HMODULE GetModuleHandleW(LPCWSTR)': cannot convert argument 1 from 'const char [11]' to 'LPCWSTR'
uintptr_t gameModule = (uintptr_t)GetModuleHandle("client.dll");
HMODULE GetModuleHandleW(LPCWSTR)': cannot convert argument 1 from
'const char [11]' to 'LPCWSTR'
"client.dll" is a char string (const char [11]).
According to the Windows API TCHAR model, GetModuleHandle is a preprocessor macro which is expanded to GetModuleHandleW in Unicode builds (the default build mode for Visual Studio C++ projects since VS 2005).
GetModuleHandleW requires a LPCWSTR string parameter, i.e. a const wchar_t*, which is a wchar-t string.
So, you have a mismatch in your GetModuleHandle call, as you passed a char string, but GetModuleHandle (which is expanded to GetModuleHandleW) requires a wchar_t string (LPCWSTR).
You can fix this error passing L"client.dll" instead of "client.dll"; in fact, L"client.dll" (note the L prefix) is a wchar_t string:
// Pass L"client.dll" instead of "client.dll"
uintptr_t gameModule = (uintptr_t)GetModuleHandle(L"client.dll");
Another option would be explicitly invoking the "ANSI" function GetModuleHandleA:
// Explicitly call GetModuleHandleA
uintptr_t gameModule = (uintptr_t)GetModuleHandleA("client.dll");
but I would stick with Unicode APIs.
You could even totally embrace the TCHAR model, and decorate your string literal with _T() or TEXT(), e.g.:
uintptr_t gameModule = (uintptr_t)GetModuleHandle(_T("client.dll"));
That would work in both ANSI and UNICODE builds.

Why does GCC accept convertion from 'const char *' to 'char *' on std::strrchr() returned value?

While adding a detailed answer, I noticed that GCC does not warn the following code while Visual C++ complains.
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = std::strrchr (CONSTSTR, '/');
// cannot convert from 'const char *' to 'char *'
*nonconst++ = 'B';
*nonconst++ = 'A';
*nonconst++ = 'D';
}
I have tested three different GCC versions:
4.1.2 on Red Hat (Linux)
4.5.3 on Cygwin (Windows)
4.7.2 on MinGW (Windows)
But all these three GCC versions compiled this code without any warning/error:
> g++ -Wall -Wextra -pedantic -ansi test.cpp && echo "success"
success
While Microsoft compiler v16 complains:
> cl -c test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(5) : error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'
Conversion loses qualifiers
(from my office, I do not have access to ideone/codepad/... to test it using other versions)
As this code uses std::strrchr, I do not understand why GCC does not complain.
const char* strrchr( const char* str, int ch ); //the code above uses this declaration
char* strrchr( char* str, int ch );
My question: Why does g++ successfully compile this code without any warning/error? Is it a bug? a feature? a miss-configuration on my side?
Actually your g++ does not accept the conversion from 'const char *' to 'char *', it's just that on your version std::strrchr() returns a char* (incorrectly, instead of a const char*).
To verify the first part of my statement, try to compile the following on your GCC versions, I predict that all will correctly issue an error:
int main()
{
const char* p = "foo";
char* q = p; // error, invalid conversion from 'const char*' to 'char*'
}
Now for the second part, I tried to compile the following minimal code, whose actual aim is to trigger an error in order to list the declared overloads of std::strrchr:
#include <cstring>
void (*p)() = &std::strrchr; // error here, with "candidates are: ..."
int main() {}
Well, with gcc 4.7.2 the message shows the expected "all non-const" and "all const" overloads:
prog.cpp:2:21: error: no matches converting function ‘strrchr’ to type ‘void (*)()’
In file included from /usr/include/c++/4.7/cstring:44:0,
from prog.cpp:1:
/usr/include/string.h:249:1: error: candidates are: char* strrchr(char*, int)
/usr/include/string.h:255:1: error: const char* strrchr(const char*, int)
i.e. the prototypes
char* strrchr( char* , int );
const char* strrchr( const char* , int ); // Question's code will use this one (-> error)
But with gcc 4.3.2 the message was different:
prog.cpp:2: error: no matches converting function 'strrchr' to type 'void (*)()'
/usr/include/string.h:171: error: candidates are: char* strrchr(const char*, int)
/usr/include/c++/4.3/cstring:118: error: char* std::strrchr(char*, int)
i.e. the overloads were
char* strrchr( const char* , int ); // Question's code would use this one (-> no error...)
char* strrchr( char* , int );
(the second one is the C++ non-const overload; but the first one is the old C version, and should instead be the C++ const overload).
This it seems that the headers (<cstring> and/or <string.h>) were incorrect on this version, and I suspect that it's the same on yours.
Edit: I found for example a discussion, a blog post and a bug report (for strchr not strrchr but it's the same story).

Cannot convert char* to WCHAR* [qt/c++]

im developin QT application, and i need to include pure C code. When i compile this code in code::blocks it was successful, maybe one warning, but when i try to compile it in QT creator, i get these 4 errors.
cannot convert 'char*' to 'WCHAR*' for argument '1' to 'UINT GetSystemDirectoryW(WCHAR*, UINT)'
cannot convert 'char*' to 'const WCHAR*' for argument '1' to 'HINSTANCE__* LoadLibraryW(const WCHAR*)'
cannot convert 'char*' to 'WCHAR*' for argument '1' to 'BOOL
cannot convert 'const char*' to 'const WCHAR*' for argument '2' to 'LONG RegQueryValueExW(HKEY__*, const WCHAR*, DWORD*, DWORD*, BYTE*, DWORD*)'
and the code is here>
char systemDirectory[MAX_PATH];
GetSystemDirectory(systemDirectory, MAX_PATH); //first error
char kbdLayoutFilePath[MAX_PATH];
kbdLibrary = LoadLibrary(kbdLayoutFilePath); //second error
char kbdName[KL_NAMELENGTH];
GetKeyboardLayoutName(kbdName); //third error
if(RegQueryValueEx(hKey, "Layout File", NULL, &varType, layoutFile, &bufferSize) != ERROR_SUCCESS) //fourth error
i also use snprintf function, so i cant just change the type from char to WCHAR, because then it wont compile the snprintf
snprintf(kbdKeyPath, 51 + KL_NAMELENGTH,
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", kbdName);
So do you have any ideas how to fix it ? first i tried change type from char to WCHAR, but then the snprintf didnt work, so i tried to use swprinf, but with no success, since strangely it didnt find this function
int swprintf(wchar_t *wcs, size_t maxlen,
const wchar_t *format, ...);
but just this
int swprintf(wchar_t *wcs,
const wchar_t *format, ...);
so what are my option ? How to compile pure C code in c++ environment without any errors... or how to make the right type conversion.
You are compiling in Unicode mode. You could set your compile to multi-byte strings. The problem that is happening is those windows API functions are macros that check whether you are building Unicode or not and then call either the W or A version of the function (in your code there, the GetSystemDirectory is actually calling GetSystemDirectoryW. So, you can either change your compile to multi-byte strings....or you could explicitly change your api calls to call the A version (i.e. GetSystemDirectoryA)
You are compiling your project with the UNICODE or _UNICODE define. Check your project settings and remove the define if necessary. To remove the define, you might need to disable unicode support for the whole project.
Change over from char to WCHAR and then to solve your swprintf problem just do this
#define swprintf _snwprintf
On Windows, the prototype of swprintf is
int swprintf( wchar_t *buffer,const wchar_t *format [,argument] ... );
But the ISO C Standard requires the following prototype for swprintf
int swprintf (wchar_t *, size_t, const wchar_t *, ...);
For this very reason, on Windows, _snwprintf is provided.
Read this for more details
http://msdn.microsoft.com/en-us/library/ybk95axf(v=vs.71).aspx

strrchr causing 'Cannot convert from const char * to char *'

I am trying to compile some code that was given to me that I'm told compiles fine. Perhaps on a different compiler. I am using VS2010 and I have the following line:
char *dot = strrchr(filename, '.');
This causes the compiler error:
"error C2440: 'initializing': cannot convert from 'const char *' to
'char *'
How come? And how do I fix it?
The error message is pretty clear. strrchr returns a const char*. So you need:
const char *dot = strrchr(filename, '.');
If you really need a char*, you can use strcpy for conversion.
C++ has saner versions of strchr and strrchr than C thanks to overloading, so say:
const char * dot = strrchr(filename, '.');
In C, which has no overloading, you only have a single function char * strrchar(const char *, const char *), and it's up to you to decide whether the result is constant or mutable, depending on which type of pointer to feed into the function. C has many such type-unsafe functions.