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

Optimize and add ability to configure error printing function #11

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

rayhamel
Copy link
Contributor

@rayhamel rayhamel commented May 31, 2021

As mentioned in the original PR #9 , fixes a potential issue when the user has called std::ios_base::sync_with_stdio(false)

Copy link
Owner

@cjdb cjdb left a comment

Choose a reason for hiding this comment

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

Thanks for splitting this into multiple commits. Before approving, I'd like to see a few tests and the documentation updated, to demonstrate the new usage.

include/cjdb/contracts.hpp Outdated Show resolved Hide resolved
include/cjdb/contracts.hpp Outdated Show resolved Hide resolved
#define CJDB_FORCE_INLINE [[gnu::always_inline]] inline
#endif // _MSC_VER

#ifndef CJDB_PRINT_ERROR
Copy link
Owner

Choose a reason for hiding this comment

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

What is this guard protecting against?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My idea is that the user could optionally define their own CJDB_PRINT_ERROR function.

Copy link
Owner

Choose a reason for hiding this comment

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

cjdb::contracts_detail is a detail namespace, so a user can't do this under the proposed model. If you want to make this configurable, please put it in namespace cjdb. I think the macro should probably be opt-out, not opt-in? Otherwise folks won't get any output in their debug builds, which would be surprising.

Copy link
Contributor Author

@rayhamel rayhamel May 31, 2021

Choose a reason for hiding this comment

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

My idea is that the user could define or choose an appropriate function under whichever namespace, then define the function-like macro CJDB_PRINT_ERROR to call that function. The cjdb::contracts_detail::print_error function is only created when CJDB_PRINT_ERROR is not already defined.

There may of course be better ways of making this configurable.

Copy link
Owner

Choose a reason for hiding this comment

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

Could you please have a think about a more C++-oriented way to configure this? You don't need to implement it just yet: come back here and post the idea, but if we can avoid a macro, that'd be great.

Copy link
Contributor Author

@rayhamel rayhamel Jun 1, 2021

Choose a reason for hiding this comment

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

I changed the implementation to use a function pointer cjdb::print_error which the user can set to something else. I still do have two macro configuration options CJDB_USE_IOSTREAM (as you know, #include <iostream> introduces some overhead, so should be opt-in) and CJDB_SKIP_STDIO, in which case there's also no dependency on cstdio and the user must provide their own definition for cjdb::print_error.

include/cjdb/contracts.hpp Outdated Show resolved Hide resolved
#define CJDB_FORCE_INLINE [[gnu::always_inline]] inline
#endif // _MSC_VER

#ifndef CJDB_PRINT_ERROR
Copy link
Owner

Choose a reason for hiding this comment

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

cjdb::contracts_detail is a detail namespace, so a user can't do this under the proposed model. If you want to make this configurable, please put it in namespace cjdb. I think the macro should probably be opt-out, not opt-in? Otherwise folks won't get any output in their debug builds, which would be surprising.

include/cjdb/contracts.hpp Outdated Show resolved Hide resolved
Copy link
Owner

@cjdb cjdb left a comment

Choose a reason for hiding this comment

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

A few more minor comments.

Test cases and documentation will need to be updated in order for this patch to be approved.

#define CJDB_FORCE_INLINE [[gnu::always_inline]] inline
#endif // _MSC_VER

#ifndef CJDB_PRINT_ERROR
Copy link
Owner

Choose a reason for hiding this comment

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

Could you please have a think about a more C++-oriented way to configure this? You don't need to implement it just yet: come back here and post the idea, but if we can avoid a macro, that'd be great.

Comment on lines 29 to 31
try {
std::clog.write(message.data(), static_cast<std::streamsize>(message.size()));
} catch(...) {}
Copy link
Owner

Choose a reason for hiding this comment

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

try/catch block isn't necessary: if the stream throws in the middle of reporting a contract violation, I think it would be more useful if the user discovered that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I got rid of that and for consistency made the stdio implementation throw when fwrite fails.

include/cjdb/contracts.hpp Outdated Show resolved Hide resolved
@rayhamel
Copy link
Contributor Author

rayhamel commented Jun 1, 2021

Thanks for splitting this into multiple commits. Before approving, I'd like to see a few tests and the documentation updated, to demonstrate the new usage.

I added tests and a section to the documentation. Thanks for the feedback and your time.

@rayhamel rayhamel requested a review from cjdb June 1, 2021 02:05
README.md Outdated Show resolved Hide resolved
inline print_error_fn* print_error = [](std::string_view message) {
#ifdef CJDB_USE_IOSTREAM
std::cerr.write(message.data(), static_cast<std::streamsize>(message.size()));
#elif !defined(CJDB_SKIP_STDIO)
Copy link
Owner

Choose a reason for hiding this comment

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

What is the motivation for skipping I/O?

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. For use in freestanding implementations that lack an output device and/or the header cstdio
  2. For users who provide their own cjdb::print_error function. While this use case is possible without a configuration option, it's not necessarily desirable to #include <cstdio> with all that implies (e.g. declaring a function called remove in the global namespace).

@cjdb
Copy link
Owner

cjdb commented Jun 6, 2021

Thanks for your patience @rayhamel. I wanted a bit of time to think over your comments, but I've been very preoccupied recently. I'll get to this as soon as I can.

@rayhamel
Copy link
Contributor Author

rayhamel commented Jun 7, 2021

Thanks for your patience @rayhamel. I wanted a bit of time to think over your comments, but I've been very preoccupied recently. I'll get to this as soon as I can.

Absolutely no rush! Thanks again for your time.

@cjdb
Copy link
Owner

cjdb commented Feb 18, 2022

Hi @rayhamel, to jog my memory on this PR (and the next one), your goal here is to add ostream support, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants