Giter Club home page Giter Club logo

icecream-cpp's People

Contributors

renatogarcia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

icecream-cpp's Issues

clang compiler : missing include header

Just to share my experience, hope it will help someone, great and useful lib, so here it is ...

Testbed :

Debian clang version 16.0.6 (15)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

Icecream : from master

Add #include <cstdarg> in icecream.hpp in order to avoid these following errors caused by this statement in mytest.cxx

using icecream::f_;

In file included from mytest.cxx:8:
./icecream.hpp:1613:58: error: unexpected type name 'T0': expected expression
            result.push_back(static_cast<T>(va_arg(args, T0)));
                                                         ^
./icecream.hpp:1628:38: error: expected '(' for function-style cast or type construction
            auto v = va_arg(args, int) & 0x01;
                                  ~~~^
./icecream.hpp:1647:43: error: expected '(' for function-style cast or type construction
            double d = va_arg(args, double);
                                    ~~~~~~^
./icecream.hpp:1674:41: error: unexpected type name 'T0': expected expression
        return Tree{(T)(T1)va_arg(args, T0), std::move(buf_)};
                                        ^
./icecream.hpp:1680:34: error: expected '(' for function-style cast or type construction
        auto i = va_arg(args, int) & 0x01;
                              ~~~^
./icecream.hpp:1694:37: error: expected '(' for function-style cast or type construction
        auto d = va_arg(args, double);
                              ~~~~~~^
./icecream.hpp:1873:9: error: use of undeclared identifier 'va_start'
        va_start(args, format);
        ^
./icecream.hpp:1926:9: error: use of undeclared identifier 'va_end'
        va_end(args);

GCC is more permissive and seems to ignore this ...

gcc (Debian 13.2.0-4) 13.2.0

Printing a std::string_view relies on a terminating null-byte

std::string str = "ABCDE";
std::string_view sub{str.data() + 1, 3};
IC(sub); 
    // expected: ic| sub: "BCD"
    // actual:   ic| sub: "BCDE"

(see https://godbolt.org/z/b3a9Eq)

I think line 703

buf << '"' << cv.to_bytes(value.data()) << '"';

should be

buf << '"' << cv.to_bytes(value.data(), value.data() + value.size()) << '"';

and maybe the Microsoft-specific code a few lines above has to be adjusted, too.
But I don't know icecream-cpp well enough to be sure.

Release a new version

Just creating a git tag, and changing the version number in CMakeLists.txt would be good.

The last release was 2 years ago, while there has been a bunch of new stuff added!

Comparison with dbg-macro

I'm used to the Python icecream library and really like this style of printf based debugging.

While looking for C++ based library, I found this repo & another one: https://github.com/sharkdp/dbg-macro

Are you aware of it? Any comparison between the two? which features one supports & the other doesn't etc?

Simplest way to print function called with the arguments that were passed

What is the simplest way to print function called with the arguments that were passed? I'm debugging an interface implementation, so I don't have so much control over who is calling me methods; rather I am on the receiving end of them being called.

I can add IC() at the beginning of a function to see its name and arguments, but the argument values themselves aren't printed.

avoid using the _() macro/function which used for text translation in other libraries

Hi, I try to use the header file, but it reported a build error.

I see that in some of my header file, the _() is defined to text translation. (For example, under wxWidgets, the _() is defined as:

 #define _(s)                               wxGetTranslation((s))

While, I see in the icecream.hpp, it also define some function like:

    template<typename... Ts>
    auto _(std::string const& fmt, Ts&&... vs) -> detail::FormatterPack<decltype(std::forward<Ts>(vs))...>
    {
        return detail::FormatterPack<decltype(std::forward<Ts>(vs))...>{fmt, std::forward<Ts>(vs)...};
    }

So, I would like to find a way to solve such conflict issue. Thanks.

Clang dump struct type info limitation

Due to limited information provided by Clang when using __builtin_dump_struct function, some struct members types can not be printed. Enums, none of them can be printed. With arrays, only the ones with elements of fundamental types, fixed width integers, std::size_t, std::ptrdiff_t, and any pointer, declared using canonical names (i.e.: not type aliases), can be printed.

When using the __builtin_dump_struct function, both enums and arrays are dumped to some_printf_func using the %p specifier, regardless of its elements type. With only that information would not be possible recover and print neither the enum values nor any array element.

However, preceding each call to some_printf_func with a %p specifier by __builtin_dump_struct, a call to that same function will be done having as argument a string with the member signature (type and name). To enums that is not of any help, but to arrays, inspecting that string is possible deduce the array size and its elements types.

Knowing that information, an array dumped with a preceding "short [50] bla" string can be deduced as being an array of 50 short int. That works identically for any fundamental type, but is not possible infer the array elements type if an alias is used. With the code:

using Integer = int;

struct Point
{
    double x;
    double y;
};

struct S
{
    Integer integers[10];
    Point coords[5];
};

there is no way to know what fundamental type Integer is an alias to, neither what are the internal members of Point struct. Consequently, both integers and coords members can not be printed.

To enums, its values are represented using an integral type defined at enum declaration, like:

enum EN : std::uint64_t
{
    UM,
    DOIS,
    TRES
};

However, inside of some_printf_func it's not possible to get that information. Therefore, not kowning the bit size of each enum value it's not possible print them.

Clang dump struct float members limitation

Due to a Clang bug, is not possible correctly print float and double struct members declared using aliased type names.

When calling variadic functions, float arguments are promoted to doubles before being passed. However, the Clang float promotion before the calling of some_printf_func, given as argument of __builtin_dump_struct, is buggy. It seems like instead of converting it to a double with the same numeric value, the float 32 bits are just copied to the first 32 bits of a double.

As a consequence of that behavior, inside of some_printf_func, if you know that your next %f specified variadic argument is a double, you can just do va_arg(args, double) as usual. On other hand, if you know that your next argument is a float, you can do double d = va_arg(args, double) and reinterpret the first 32 bits with *((float*)&d). However, if you don't know if your argument is either a double or a float, it won't be possible decide between interpret the whole 64 bits as a double or the first 32 bits as a float.

When using the __builtin_dump_struct function, a %f specifier will be used to both float and double arguments indistinctly. Luckily, preceding each call to some_printf_func with a % specifier, a call to that same function will be done having as argument a string with the variable signature (type and name). So, inspecting that string would be possible deduce the variable type before its promotions to a double. The %f argument with a "const float foo" string must be a float, and with a "double bar" must be a double.

However, if the %f argument has been declared with an aliased type name, its inference as float or double is not possible. With the code:

using MyNumber = float;
struct S
{
    MyNumber num;
};

, when dumping the struct S, the information of num variable being either float or double is lost. The IceCream-cpp approach is presume num as a double, but print its value alongside a warning.

Summarizing, float and double struct members declared with canonical names will work just fine. If a name alias is used, on IceCream-cpp side is not possible distinguish between them, and a double type is presumed. If num is a double the printed value is correct, if it is a float the printed value is wrong.

Linking errors

I was using version 0.1.0 of icecream-cpp for a while, and I have IC statements in multiple source files, which are compiled independently (as cmake object libraries) and then linked together into different binaries and shared libraries. This used to work very nicely. Now I upgraded to 0.3.0, recompiled everything, and get linking errors like so:

multiple definition of `icecream::detail::show_c_string()'

I know that this is potentially an issue with header only libraries in general, but perhaps there is something you can do, as it used to work in previous versions.

cannot display char as integer

CleanShot 2022-09-03 at 10 51 31@2x

#include <algorithm>
#include <numeric> 

#include "icecream.hpp"

using namespace std;

#define DETECT_TYPE(x)                        \
    do                                        \
    {                                         \
        IC(sizeof(x));                        \
        IC_("d", std::numeric_limits<x>::max());    \
        IC_("d", std::numeric_limits<x>::min());    \
        IC_("d", std::numeric_limits<x>::lowest()); \
    } while (0)


int main(int argc, char **argv)
{
    DETECT_TYPE(char);
    DETECT_TYPE(unsigned char);
    return 0;
}

expect: it should display max: 128, min: -127, lowest: -127
gcc 11.2 linux

containers are not properly displayed when they are members of a user-defined class

I'm trying to print an instance of a user-defined class as follows.

  class MyStruct {
    public:
    int i;
    double d;
    std::string s;
    std::vector<int> v;
  };

  MyStruct x;
  x.i = 2; x.d = 0.9; x.s = std::string("abc"); x.v = {1, 2, 3};     // set member variables
  IC(x);

What I expected was something like

ic| x: {i: 2, d: 0.9, s: "abc", v: [1, 2, 3]}

but what I actually got was the following.

ic| x: {i: 2, d: 0.9, s: {__r_: {}}, v: {}}

It seems that a member variable is not properly displayed when it is an STL container. If I print each member IC(x.s, x.v), I got the correct output. Could someone investigate this issue?

FYI, my compiler is Apple clang version 11.0.0 (clang-1100.0.33.17).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.