Comments (17)
I second the case that multiple arguments is very useful. I had already used this widely before the change was reverted, so for now I'm stuck on the old version of dbg()
until/if this is fixed.
A third option would be to return the last value, similar to how the comma operator works.
from dbg-macro.
Could we reopen this issue since the commit is reverted?
Quote from #8 (comment)
I actually just reverted the merge - I should have tested this first, sorry. Allowing for multiple arguments like I described in #2 is not compatible with using
dbg(β¦)
in expressions. I would really like to keep that functionality.I should have thought about this before writing #2.
If we allow for
dbg(x, y, β¦)
, we would have to make a rather arbitrary choice of just returningx
.\
I think multiple arguments is a more common use case than returning from expressions. I have a similar debugging macro locally and I use it with multiple args from day to day. If we would like to support them at the same time, there are some possible routes:
- Only returns
x
fromdbg(x)
, and returns void for multiple args case. - Similar to Rust, returns a tuple when there are multiple args.
from dbg-macro.
I think multiple arguments is a more common use case than returning from expressions.
Good point. I think the dbg(β¦)
-inside-expressions usage is actually surprisingly useful, once you get used to it, but I would tend to agree with your statement.
- Only returns
x
fromdbg(x)
, and returns void for multiple args case.- Similar to Rust, returns a tuple when there are multiple args.
I think I would go with the first option and return void
(or even "disallow" the usage with multiple arguments within an expression). I don't think it's very likely that someone will work with the tuple that would be returned in the second case.
from dbg-macro.
I actually like that even better, just return the last argument.
from dbg-macro.
Unfortunately, this request has to be closed.
There is no clean way to implement multiple argument support without losing another feature: unprotected commas within the dbg(β¦)
call. This is due to a limitation of the preprocessor which does not properly parse commas within curly {β¦}
braces or template argument lists <β¦>
. So things like
dbg(MyClass{1,2,3});
or
dbg(my_template_function<int, 2>());
wouldn't work anymore.
Even if those things would still work with additional parenthesis (dbg((β¦))
), I think that it would be surprising for a lot of users.
For a detailed discussion, see #64.
from dbg-macro.
Yes there is no perfect solution here, but I would lean to support multiple arguments instead of unprotected commas:
- Multiple arguments is a common needed scenario and no easy workaround.
- Unprotected commas can be workaround by adding parenthesis, and is widely used in popular libs, such as googletest, and Catch2.
from dbg-macro.
Fair points. Opening this once again π
Multiple arguments is a common needed scenario and no easy workaround.
well, the workaround is to dbg(x); dbg(y); dbg(z);
instead of dbg(x, y, z);
from dbg-macro.
Unprotected commas can be workaround by adding parenthesis, and is widely used in popular libs, such as googletest, and Catch2.
Catch2 is also a counter-example. For all of its one-argument macros (CHECK(β¦)
, REQUIRE(β¦)
, ..), you can use unprotected commas.
from dbg-macro.
Fair points. Opening this once again π
Multiple arguments is a common needed scenario and no easy workaround.
well, the workaround is to
dbg(x); dbg(y); dbg(z);
instead ofdbg(x, y, z);
Ah sure.
Unprotected commas can be workaround by adding parenthesis, and is widely used in popular libs, such as googletest, and Catch2.
Catch2 is also a counter-example. For all of its one-argument macros (
CHECK(β¦)
,REQUIRE(β¦)
, ..), you can use unprotected commas.
That's why I link to the CAPTURE() macro directly :P
Catch2 even parses / splits the expressions in the CAPTURE() macro by itself, so it can handle some of the unprotected commas. Note that because C++ is a context sensitive, thus it's quite hard (if not impossible) to disambiguate code like X<0>(1)
correctly in this way.
Another hybrid approach is making output as x, y = 1, 2
instead of x = 1, y = 2
. The names are just taken from dbg(...)
directly, and the values are forwarded to a variadic template function, which should parse the arguments correctly.
from dbg-macro.
Another hybrid approach is making output as
x, y = 1, 2
instead ofx = 1, y = 2
. The names are just taken fromdbg(...)
directly, and the values are forwarded to a variadic template function, which should parse the arguments correctly.
Hm. I don't quite understand. How would this work?
from dbg-macro.
Here is a minimal proof-of-concept:
#include <iostream>
#include <utility>
template <class T, class... U>
void dbg_impl(T &&head, U &&... tail) {
std::cerr << head;
if constexpr (sizeof...(U) > 0) {
std::cerr << ", ";
dbg_impl(std::forward<U>(tail)...);
} else {
std::cerr << "\n";
}
}
#define dbg(...) \
do { \
std::cerr << #__VA_ARGS__ << " = "; \
dbg_impl(__VA_ARGS__); \
} while (false)
int main() {
int x = 1;
int y = 2;
dbg(x, y, std::pair<int, int>(x, y).first);
return 0;
}
It will output:
x, y, std::pair<int, int>(x, y).first = 1, 2, 1
from dbg-macro.
@ShikChen If we can make this work with the type-output as well (and pass all the tests that are currently in place), I think that would be a great compromise.
from dbg-macro.
- Unprotected commas can be workaround by adding parenthesis, and is widely used in popular libs,
Came here to say this, but @ShikChen beat me to it.
from dbg-macro.
Okay, so you are voting to drop the "commas inside dbg(β¦)" feature in favor of multiple arguments? I think I'm now also inclined to do so.
In this case, I would prefer the solution where dbg(x, y, z)
has the same output as dbg(x)
, dbx(y)
, dbg(z)
.
from dbg-macro.
Note that there is an implementation of multiple arguments here: #8. It was reverted because it did not return the value, but I guess that could be fixed easily. Not sure if there are other implementations that would need less preprocessor code.
from dbg-macro.
I have a simple proof of concept, and I think we need to decide what's the expected behavior when multiple arguments are used with the special helpers that don't print the type and expressions, such as dbg(dbg::time(), 1 + 2)
.
Currently there are 3 special cases we dbg()
won't print the type and original expression:
- C string literal (
const char (&value)[N]
) dbg::time
dbg::type
Here is an example:
#include <dbg.h>
#define NAME "bar"
typedef uint64_t u64;
int main() {
dbg("foo");
dbg(NAME);
dbg(dbg::time());
dbg(dbg::type<u64>());
// dbg(dbg::time(), 1 + 2, "meow"); // won't compile in the current version
return 0;
}
Current output is:
[shik.cc:7 (main)] foo
[shik.cc:8 (main)] bar
[shik.cc:9 (main)] current time = 18:25:00.066772
[shik.cc:10 (main)] unsigned long long [sizeof: 8 byte, trivial: yes, standard layout: yes]
I personally prefer to output:
[shik.cc:7 (main)] foo
[shik.cc:8 (main)] NAME = bar (const char*)
[shik.cc:9 (main)] dbg::time() = 18:25:00.066772 (dbg::time)
[shik.cc:10 (main)] dbg::type<u64>() = unsigned long long [sizeof: 8 byte, trivial: yes, standard layout: yes] (dbg::type)
[shik.cc:11 (main)] dbg::time(), 1 + 2, "meow" = 18:25:00.067083, 3, meow (dbg::time, int, const char*)
Does it look ok to you?
(I also prefer to shorten the type info as [8 bytes, trivial, standard layout]
and reduce the timestamp precision to millisecond, but that's orthogonal to the multiple arguments issue)
from dbg-macro.
I have a simple proof of concept
That sounds great!
and I think we need to decide what's the expected behavior when multiple arguments are used with the special helpers that don't print the type and expressions
Why? My preferred way how multiple arguments would work would be that the output of dbg(x, y, z);
is the same as dbg(x); dbg(y); dbg(z);
. I find the x, y, z = x_value, y_value, z_value
a bit confusing and non-optimal.
[shik.cc:8 (main)] NAME = bar (const char*)
I'm pretty sure that wouldn't work because NAME
will be replaced by the preprocessor.
(I also prefer to shorten the type info as
[8 bytes, trivial, standard layout]
and reduce the timestamp precision to millisecond, but that's orthogonal to the multiple arguments issue)
Yeah, let's discuss this in separate tickets.
from dbg-macro.
Related Issues (20)
- Windows Supported? HOT 14
- Broken output of containers HOT 6
- How about output "{?}" string for unknown types instead of failing with static assert? HOT 2
- Allow specifying the output stream HOT 9
- Is support it for android ? HOT 2
- Is it possible to allow variadic template expansion? HOT 8
- VS2015οΌerror C2912 HOT 5
- debug print on some condition HOT 3
- use in Qt HOT 1
- Add output level HOT 2
- `Type does not support the << ostream operator` on custom type HOT 10
- multithread support HOT 1
- Support always on colors HOT 2
- Nested dbg(...) expansion as not expected HOT 2
- How to force print the full content, not the one with ellipsis HOT 3
- Support for container adapters HOT 1
- Fails with Eigen matrices HOT 7
- Suggest /usr/local/include instead of /usr/include HOT 3
- Report a compiling error with old GCC version (GCC 4.8.5) HOT 1
- Some enhancement proposals for CMake based usecases HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dbg-macro.