--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF1j9YO-7-Z_71kJVDPgZ9DCgiPZeDs7jnpKo3iBid5%3Doyo3VA%40mail.gmail.com.
HRESULT hr = Foo1();if (FAILED(hr))return hr;hr = Foo2();if (FAILED(hr))return hr;hr = Foo3();if (FAILED(hr))return hr;Usually I am not a fan of having "return" in macros, which harms readability IMHO, though I can't find the actual style guide against it. The current style guide only says "try not to use macros that expand to unbalanced C++ constructs", which isn't exactly the case here.The real issue here is that without this macro, the code would be much longer with a lot of if/returns. (Some functions I am looking at have ~20 Windows API calls.) This seems to hurt readability in a different way. Here's an existing example. It's even worse since it does logging, which is a separate topic.
Sorry I wasn't clear. I am using these two simple examples to show the core problem. In reality, you can have various branching (e.g. if/else blocks) where both suggestions won't work. Here's a more realistic example (the CHK is similar to RETURN_IF_FAILED in this discussion).
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFAq%3Da8jUtKCRJonA9-ptWzqasL2G%2BbAQ%2BZh30TF0WyY%2BQ%40mail.gmail.com.
How about making use of short-circuiting, along with a helper class to track states? Then you can have just one return at the end. Example:================================#include <cstdio> using HRESULT = int; constexpr HRESULT S_OK = 0; constexpr HRESULT S_FAIL = 1; class WinOkay { public: WinOkay() {} ~WinOkay() {} operator bool() { return last_result_ == S_OK; } bool operator()(HRESULT res, const char* err_msg) { if (res != S_OK) { last_result_ = res; err_msg_ = err_msg; return false; } return true; } HRESULT verdict() { if (last_result_ != S_OK && *err_msg_) { printf("Error message: %s\n", err_msg_); } return last_result_; } private: HRESULT last_result_ = S_OK; const char* err_msg_ = ""; }; HRESULT fun1() { printf("Calling fun1()\n"); return S_OK; } HRESULT fun2() { printf("Calling fun2()\n"); return S_OK; } HRESULT fun3() { printf("Calling fun3()\n"); return S_FAIL; } HRESULT fun4() { printf("Calling fun4()\n"); return S_OK; } HRESULT fun5() { printf("Calling fun5()\n"); return S_OK; } HRESULT fun() { WinOkay ok; ok && ok(fun1(), "Failed in fun1()."); if (ok && ok(fun2(), "Failed in fun2().")) { ok && ok(fun3(), "Failed in fun3()."); } ok && ok(fun4(), "Failed in fun4()."); ok && ok(fun5(), "Failed in fun5()."); return ok.verdict(); } int main() { return fun(); }================================
I suppose that we have the following conflicting objectives:
- Short code.
On Fri, Jan 10, 2020 at 2:35 PM Samuel Huang <hua...@chromium.org> wrote:I suppose that we have the following conflicting objectives:
- Short code.
I would always prefer obvious code over short code.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAHtyhaQVOjnpwJJX8JnPQMz7T%2BBgS-4QLh_Wpo57a_fsLYGbRQ%40mail.gmail.com.
I hope I didn't leave the impression that I was purely looking for shorter code. I was more concerned about readability than the length of code. I felt that having too many "if(FAILED(...)) return" breaks the flow of the code and makes things harder to read and follow.I don't think we can simply DCHECK Windows APIs even for simple things like IMFAttributes::SetUINT32(). A CHECK() could cause the GPU/Browser process to crash, which also seems to violate the current recommendation.
On Fri, Jan 10, 2020 at 5:12 PM Xiaohan Wang (王消寒) <xhw...@chromium.org> wrote:I hope I didn't leave the impression that I was purely looking for shorter code. I was more concerned about readability than the length of code. I felt that having too many "if(FAILED(...)) return" breaks the flow of the code and makes things harder to read and follow.I don't think we can simply DCHECK Windows APIs even for simple things like IMFAttributes::SetUINT32(). A CHECK() could cause the GPU/Browser process to crash, which also seems to violate the current recommendation.Why can't we? Many functions can fail depending on their inputs, but if we know and control their inputs then we can expect them to always succeed. This one in particular can't fail so why can't we expect it to always succeed? Is this for future compatibility or excessive defensiveness or something else?
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF1j9YP0tGbAp3sowiwKRqCxrEhwM0x0d-r15cme7F8Q%3DWP_nA%40mail.gmail.com.
On Fri, Jan 10, 2020 at 2:40 PM <dan...@chromium.org> wrote:
On Fri, Jan 10, 2020 at 2:35 PM Samuel Huang <hua...@chromium.org> wrote:I suppose that we have the following conflicting objectives:
- Short code.
I would always prefer obvious code over short code.+1. Short is nice insofar as it lets you fit more of the code in your head at once, but clarity is the goal. I'm fairly unconvinced that just having a (D)CHECK that something didn't fail (if we believe it cannot) or a conditional statement (if we believe it might) isn't the right solution. That's what we do nearly everywhere else.
- Being explicit about return.
- Expressive flexibility (to pass params, or conditional calls).
The "WinOkay" method satisfies the above, but is weak in:
- Avoid incessant checks
Anyway, it looks like you're settling with the original method (which I have no objection to).More thinking (for fun): In JavaScript one would likely use Promises. If generators are available then one can yield the return value for each call, and a caller can pump the loop and handle the error. Ah language features envy...
On Fri, Jan 10, 2020 at 12:30 PM Xiaohan Wang (王消寒) <xhw...@chromium.org> wrote:
On Fri, Jan 10, 2020 at 8:17 AM Samuel Huang <hua...@chromium.org> wrote:
How about making use of short-circuiting, along with a helper class to track states? Then you can have just one return at the end. Example:================================
(...) ================================
Thanks for the suggestions. I guess the requirement that you have to check |ok| everywhere afterwards is troublesome. Also, this prevents us from returning early, which we favor a lot. Actually, anywhere in your function, you can doif (!ok)return ok.verdict();But then that's back to the case where we don't use the macro.--Samuel HuangOn Thu, Jan 9, 2020 at 3:15 PM Peter Kasting <pkas...@chromium.org> wrote:--On Thu, Jan 9, 2020 at 8:48 AM Xiaohan Wang (王消寒) <xhw...@chromium.org> wrote:Sorry I wasn't clear. I am using these two simple examples to show the core problem. In reality, you can have various branching (e.g. if/else blocks) where both suggestions won't work. Here's a more realistic example (the CHK is similar to RETURN_IF_FAILED in this discussion).It's a challenging problem in general, and I don't know that any one answer is best everywhere. It seems like you're considering the right factors, and as you note the style guide allows for different routes here, so whatever you decide should be OK.One tactic that might be helpful in reducing the need for macros is to try to avoid propagating system types or information out of functions unless necessary. So where things return HRESULT, do callers need that level of detail, or can they just get a bool "operation failed" or Optional or something? If the returned value is primarily used for logging, is it already logged in the child function? This might open more avenues for rewriting the code in a way that either doesn't use macros or can use shorter/simpler ones.But in the limit, you may wind up with a macro really being the best possible answer in some scenario. If so go for it.PK
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFAq%3Da8jUtKCRJonA9-ptWzqasL2G%2BbAQ%2BZh30TF0WyY%2BQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF1j9YNyh3o9CNQ%2BEPb-ASMVsURApaE9WVjpCb4QkTVwXQaNkw%40mail.gmail.com.