Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add available macros for 'return error code' as an alterative to 'verifyorexit' #3880

Merged
merged 7 commits into from
Nov 19, 2020

Conversation

andy31415
Copy link
Contributor

Problem

Existing coding pattern of 'exit:' goto label is convenient for cleanup code, however it encourages C-style coding which has drawbacks:

  • less use of RAII (typical C++ cleanup)
  • forces variable declarations to be at the top of the scope due to the goto statement, moving variables further away from their usage.

Summary of Changes

Creates Verify/return macros that are equivalent to the 'exit' macros and converts some files with sample usage for these macros.

Generated code is generally the same size as the previous goto code (with some slight immaterial improvements) and source code is shorter.

Convert a few more rendezvous to return macros instead of verify - seems 0 code size difference
Copy link
Contributor

@rwalker-apple rwalker-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yay! on our way to no labels?

@andy31415
Copy link
Contributor Author

yay! on our way to no labels?

I am not a fan of goto. I understand it is useful for embedded, but it should not be forced on me. I would like everyone to have a choice.


if (endPoint != nullptr)
{
err = endPoint->Send(msgBuf);
return endPoint->Send(autofree.Release());
}
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's our general position on else after return?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally prefer single point of return or exit / error handling (RAII or not) which moots this particular facet of coding style discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created this PR after seeing that mandating goto with single point of exit can result in significantly hard to follow code.

The premise is that we will have the option to use return if the code is cleaner as a result. Mandating exit label always seems too strong of a requirement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the else after return: I think generally I would say no else is needed after return. In this particular case however, this is a final statement that reads like:

return (endpoint != nullptr)
    ? endPoint->Send(autofree.Release())
    : SendAfterConnect(address, autofree.Release());

so I thought else helps clarity. I would drop the else if the readability reviews would ask for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I support @gerickson. Probably it's a matter of taste and it will be hard to decide on "the right" approach. For me this change makes code less readable and more error-prone (especially if we'll start mixing e.g. VerifyOrExit with VerifyOrReturn in a single method). But maybe it's just my embedded background..

Of course giving the choice for developers is good, though we lose consistency when both approaches are used in different places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 that mixing in a single method would be absolutely bad - you get the benefit of neither. I am not arguing for that. I am arguing that I should be allowed to use return if it makes the code easier/clearer to read.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could not find a good way to count, but find . -type f | egrep -v '/third_party/' | xargs egrep -zc 'exit:\s*return' | grep -v ':0' | wc -l seems to indicate that there are 149 instances today where 'exit: return...' is used. I believe those instances would benefit from just using return in the first place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C forces you into the goto exit pattern, but C++ doesn't, and the goto style with declarations front loaded seems unusual for C++. Google's style guide doesn't even bother to recommend against using goto because it is so uncommon in the first place [1].

[1] https://google.github.io/styleguide/cppguide.html#Goals

@github-actions
Copy link

Size increase report for "nrfconnect-example-build" from 188a35f

File Section File VM
chip-shell.elf rodata -40 -40
chip-shell.elf text -2448 -2448
chip-lighting.elf rodata -32 -36
chip-lighting.elf text -2496 -2496
chip-lock.elf rodata -40 -40
chip-lock.elf text -2496 -2496
Full report output
BLOAT REPORT

Files found only in the build output:
    report.csv

Comparing ./master_artifact/chip-shell.elf and ./pull_artifact/chip-shell.elf:

sections,vmsize,filesize
.shstrtab,0,1
.debug_aranges,0,-8
rodata,-40,-40
.debug_frame,0,-44
.debug_ranges,0,-72
.debug_str,0,-81
.debug_line,0,-405
.debug_loc,0,-515
.strtab,0,-769
.debug_info,0,-779
.symtab,0,-1088
text,-2448,-2448

Comparing ./master_artifact/chip-lighting.elf and ./pull_artifact/chip-lighting.elf:

sections,vmsize,filesize
.debug_ranges,0,240
.shstrtab,0,-2
.debug_aranges,0,-8
.debug_abbrev,0,-35
rodata,-36,-32
.debug_frame,0,-52
.debug_str,0,-82
.debug_info,0,-373
.debug_line,0,-720
.strtab,0,-762
.symtab,0,-1088
.debug_loc,0,-1114
text,-2496,-2496

Comparing ./master_artifact/chip-lock.elf and ./pull_artifact/chip-lock.elf:

sections,vmsize,filesize
.debug_ranges,0,240
.shstrtab,0,-2
.debug_aranges,0,-8
.debug_abbrev,0,-35
rodata,-40,-40
.debug_frame,0,-52
.debug_str,0,-82
.debug_info,0,-373
.debug_line,0,-720
.strtab,0,-762
.symtab,0,-1088
.debug_loc,0,-1106
text,-2496,-2496


@github-actions
Copy link

Size increase report for "esp32-example-build" from 188a35f

File Section File VM
chip-all-clusters-app.elf .flash.rodata -4 -4
chip-all-clusters-app.elf .flash.text -4 -4
chip-all-clusters-app.elf .dram0.data -8 -8
Full report output
BLOAT REPORT

Files found only in the build output:
    report.csv

Comparing ./master_artifact/chip-all-clusters-app.elf and ./pull_artifact/chip-all-clusters-app.elf:

sections,vmsize,filesize
.debug_info,0,319
.debug_ranges,0,104
.debug_abbrev,0,49
.debug_frame,0,24
[Unmapped],0,12
.debug_aranges,0,8
.strtab,0,7
.shstrtab,0,-3
.flash.rodata,-4,-4
.flash.text,-4,-4
.debug_str,0,-7
.dram0.data,-8,-8
.debug_loc,0,-76
.debug_line,0,-149



if (endPoint != nullptr)
{
err = endPoint->Send(msgBuf);
return endPoint->Send(autofree.Release());
}
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C forces you into the goto exit pattern, but C++ doesn't, and the goto style with declarations front loaded seems unusual for C++. Google's style guide doesn't even bother to recommend against using goto because it is so uncommon in the first place [1].

[1] https://google.github.io/styleguide/cppguide.html#Goals

@rwalker-apple rwalker-apple merged commit d513b63 into project-chip:master Nov 19, 2020
@andy31415 andy31415 deleted the 01_return_macros branch October 28, 2021 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants