c42f / tinyformat

Minimal, type safe printf replacement library for C++
531 stars 75 forks source link

error: invalid static_cast from type ‘const void*’ to type ‘void (*)()’ #72

Open evandrocoan opened 4 years ago

evandrocoan commented 4 years ago
#include<iostream>
#include "tinyformat.h"

void fun_void_void(){};

int main(void) {
    std::cout << std::boolalpha;
    std::cout << fun_void_void << std::endl;
    std::cout << tfm::format( "1. %s", fun_void_void ) << std::endl;
    return 0;
}

Calling std::cout << fun_void_void works fine, but tfm::format( "1. %s", fun_void_void ) (either %s or %p) results in:

$ g++ -o main.exe -g -ggdb test_debugger4.cpp --std=c++11 && ./main.exe
In file included from test_debugger4.cpp:2:0:
tinyformat.h: In instantiation of ‘static void tinyformat::detail::FormatArg::formatImpl(std::ostream&, const char*, const char*, int, const void*) [with T = void(); std::ostream = std::basic_ostream<char>]’:
tinyformat.h:545:38:   required from ‘tinyformat::detail::FormatArg::FormatArg(const T&) [with T = void()]’
tinyformat.h:1000:32:   required from ‘tinyformat::detail::FormatListN<N>::FormatListN(const Args& ...) [with Args = {void()}; int N = 1]’
tinyformat.h:1053:20:   required from ‘tinyformat::detail::FormatListN<sizeof... (Args)> tinyformat::makeFormatList(const Args& ...) [with Args = {void()}]’
tinyformat.h:1089:37:   required from ‘void tinyformat::format(std::ostream&, const char*, const Args& ...) [with Args = {void()}; std::ostream = std::basic_ostream<char>]’
tinyformat.h:1098:11:   required from ‘std::string tinyformat::format(const char*, const Args& ...) [with Args = {void()}; std::string = std::basic_string<char>]’
test_debugger4.cpp:9:54:   required from here
tinyformat.h:568:57: error: invalid static_cast from type ‘const void*’ to type ‘void (*)()’
             formatValue(out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T*>(value));
                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
tinyformat.h: In instantiation of ‘static int tinyformat::detail::FormatArg::toIntImpl(const void*) [with T = void()]’:
tinyformat.h:545:38:   required from ‘tinyformat::detail::FormatArg::FormatArg(const T&) [with T = void()]’
tinyformat.h:1000:32:   required from ‘tinyformat::detail::FormatListN<N>::FormatListN(const Args& ...) [with Args = {void()}; int N = 1]’
tinyformat.h:1053:20:   required from ‘tinyformat::detail::FormatListN<sizeof... (Args)> tinyformat::makeFormatList(const Args& ...) [with Args = {void()}]’
tinyformat.h:1089:37:   required from ‘void tinyformat::format(std::ostream&, const char*, const Args& ...) [with Args = {void()}; std::ostream = std::basic_ostream<char>]’
tinyformat.h:1098:11:   required from ‘std::string tinyformat::format(const char*, const Args& ...) [with Args = {void()}; std::string = std::basic_string<char>]’
test_debugger4.cpp:9:54:   required from here
tinyformat.h:574:45: error: invalid static_cast from type ‘const void*’ to type ‘void (*)()’
             return convertToInt<T>::invoke(*static_cast<const T*>(value));
                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
jrohel commented 4 years ago

The solution may be to replace *static_cast<const T*>(value) to reinterpret_cast<const T*>(value). But I'm not sure without analysing the code. The reinterpret_cast<> must be used carefully. It's just a quick idea.