I am trying to compile ustl C++ library with MinGW GCC compiler on Windows 10.
The 41st line in the C++ header below was able to solve thanks to this answer, but there is a problem at line 43. How should I solve it?
https://github.com/msharov/ustl/blob/master/fstream.h#L41
// int ioctl (const char* rname, int request, long argument = 0); // orig
int ioctl (const char* rname, int request, long argument = 0u);
inline int ioctl (const char* rname, int request, int argument) { return fstream::ioctl (rname, request, long(argument)); }
inline int ioctl (const char* rname, int request, void* argument) { return fstream::ioctl (rname, request, intptr_t(argument)); }
MinGW GCC compiler (10.3.0 (Rev5, Built by MSYS2 project)) error message:
fstream.h:43:132: error: call of overloaded 'ioctl(const char*&, int&, uintptr_t)' is ambiguous
43 | inline int ioctl (const char* rname, int request, void* argument) { return fstream::ioctl (rname, request, uintptr_t(argument)); }
--
Edit: Thanks for the hint.
With another answer, below code works for me:
https://github.com/msharov/ustl/blob/master/fstream.h#L43
// ... intptr_t(argument)); // orig
*((long*)(argument)));
You can find in the last few words that
fstream.h:43:132: error: call of overloaded 'ioctl(const char*&, int&, uintptr_t)' is ambiguous 43 | inline int ioctl (const char* rname, int request, void* argument) { return fstream::ioctl (rname, request, uintptr_t(argument)); }
intptr_t is actually a uintptr_t in your environment. And as for uintptr_t, you can find in cppreference that it's an unsigned integer.
According to ranking of implicit conversion sequence in overload resolution, unsigned sth => long and unsigned sth => int are equivalent(both conversion). So no winner, all loser, which leads to compilation error.
If you just want to avoid compilation error, convert intptr_t to long helps. But I think the best way is to use proper type that stands for its meaning. For example, if it's for an address, then just use uintptr_t in the beginning, and make it a convention.
Related
I have overloaded function
int put_message(int level, int sys_log_level, const char * inp_message);
int put_message(int level, int sys_log_level, const std::string &inp_message);
and call this function
put_message(0, LOG_ERR, "clock_gettime error");
Code is compiled and works
but Eclipse CDT Code analyzer says
Invalid arguments '
Candidates are:
int put_message(int, int, const char *)
int put_message(int, int, const ? &)
'
How can I fix this the error?
Update:
After modifying LOG_ERR to int(LOG_ERR) error disappears.
I have not add the in the header.
Adding solves the problem.
you are missing #include <string> or something related to string class
You need to cast the string to the correct type, the compiler treats "some string" as char[] so you need to cast it to const char*
Try with
put_message(0, LOG_ERR, (const char*)"clock_gettime error");
I want to override open from libc using LD_PRELOAD:
#include <dlfcn.h>
#include <sys/stat.h>
extern "C" {
int open(const char *path, int flags, mode_t mode)
{
int (*originalOpen)(const char *path, int flags, mode_t mode);
originalOpen = reinterpret_cast<decltype(originalOpen)>(dlsym(RTLD_NEXT, "open"));
//originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));
//...
return (*originalOpen)(path, flags, mode);
}
}
I compile with g++ -fPIC -shared -o open.so open.cpp -ldl.
Can somebody tell me why the above code works, and why I get the errror:
error: invalid cast from type ‘void*’ to type ‘int(const char*, int, mode_t)’ {aka ‘int(const char*, int, unsigned int)’}
originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));
when I initialize originalOpen with the line commented out?
I used gcc version 8.0.1.
Try this code:
originalOpen = reinterpret_cast<decltype(open) *>(dlsym(RTLD_NEXT, "open"));
Decltype gets the type of the function while You want to create function pointer. There is implicit cast from function to pointer of its type but these are not equivalent. This is why version with decltype(original_open) works perfectly - type of original_open is function pointer and not the function.
I am trying to create a user defined literal but get an error message when using it.
GCC says
unable to find numeric literal operator ‘operator""_uint’
while clang tells me
error: no matching literal operator for call to 'operator""_uint' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template
I reduced the code to following MCVE:
#include <cinttypes>
unsigned int operator"" _uint(char const *, std::size_t) { return 0; }
int main() {
return 1_uint;
}
Which gives the mentioned error as you can see on ideone.
As you can read in detail on cppreference.com there is a multitude of different versions for literal operators.
The one in the OP is used exclusively for string literals and won't be available for integers. Instead the "fallback" version for integers which expects only a const char* without a second std::size_t parameter:
#include <cinttypes>
unsigned int operator"" _uint(char const *) { return 0; }
int main() {
return 1_uint;
}
Which works on ideone.
When compiling the below code, it gives me a warning, namely
deprecated conversion from string constant to 'char*'.
In what ways is it possible to remove the message (without explicitly suppressing the warning)?
I tried casting with (const char*), but to no avail.
#include <windows.h>
int main() {
typedef int * (*MyDownloadToUrl)(void*, char*, char*, DWORD, void*);
HINSTANCE LibHnd = LoadLibrary("Urlmon.dll");
MyDownloadToUrl MyDownloadFunction = (MyDownloadToUrl)GetProcAddress(LibHnd,"URLDownloadToFileA");
MyDownloadFunction(0, "http://MyWebsite.com", "Webpage.htm", 0, NULL);
}
You need to const_cast<char*>("my string literal") to get rid of the warning. In C++03 implicit conversion from a string literal (which is a const char*) to char* is deprecated. In C++11 such an implicit conversion is an error.
In this case though, URLDownloadToFile takes arguments of type LPCTSTR, which is defined as either const wchar_t* or const char* depending on the UNICODE prepossessor directive.
I am trying to understand what the currenct C++14 standard says about resolving an ambiguous function call, mostly because I am seeing a difference between GCC 4.9.1, and Visual Studio 2013 update 3
Here's the code (exactly the same for both MS and GCC):
#include <iostream>
using namespace std;
void f(char *str, int chars) { cout << "f(char*, int)"; }
void f(char *first, char *second) { cout << "f(char*, char*)"; }
int main()
{
char *hello = "Hello, World";
f(hello, NULL); //which f gets called?
char c; cin.get(c);
return 0;
}
Visual Studio calls f(char*, int) using default vs flags
GCC gives me a compiler error: call of overloaded 'f(char*&, NULL)' is ambiguous. gcc using only the -std=c++11 flag.
It depends on what NULL is defined to be.
MSVC defines it as 0, so the int overload is an exact match and is preferred.
GCC defines it as the compiler internal __null, causing an ambiguity on 64-bit because __null's type there is long. (It appears that __null's type is int on 32-bit, so it picks the int overload when compiling for 32-bit.)
The standard permits NULL to be defined as any C++ null pointer constant, including nullptr, in which case it would unambigously pick the two pointer overload, or 0L, which would be once again ambiguous (as going from a long to both int and char * involves a conversion).
The moral: Don't use NULL for a null pointer. Use nullptr.