microsoft / gsl Goto Github PK
View Code? Open in Web Editor NEWGuidelines Support Library
License: Other
Guidelines Support Library
License: Other
array_view.h is already including , but doesn't seem to use it (string_view.h does). Is there a reason for this helper?
As requested, this is a report that the library builds and works with FreeBSD 10.x. The default system c++ compiler (clang 3.4) is too old, but installing the clang36
package and setting -DCMAKE_CXX_COMPILER=clang++36
or -DCMAKE_CXX_COMPILER=clang++37
when installing results in all tests passing.
The name of your codebase is GSL. Why do you have a separate abbreviation for the namespace? I'd prefer that your types be under "gsl::"
Having macros that are not prefixed by the library name is a bad practice as in
#define Expects(x) Guide::fail_fast_assert((x))
#define Ensures(x) Guide::fail_fast_assert((x))
Usually we use UPPERCASE letters for macros.
In addition, we have inline functions in C++, so no need for a macro that call another function ;-)
Final_act does not check that the object to be invoked is no-except invokable or try to catch any generated exceptions. This could be bad if multiple final acts are used to clear up state on scope exit.
Either Final_act should catch exceptions or there should be an requirement that the invokable object cannot throw exceptions when invoked. It may be desirable to have two implementations of Final_act:
Final_act and Final_act_noexcept which try and catch exceptions or do not depending on the noexcept status of the invokable object.
As per Core Guidelines.
The move constructor does not flag the moved-from object as non-invokable
auto invocation_count = 0;
auto f = finally([&invocation_count]{ ++invocation_count;});
assert(invocation_count == 1);
If the copy-by-rvalue-reference is not elided (which is possible but not necessary) then the invocation count will be 2. The final_act
object needs an internal bool to track its state or the C++ standard needs to require copy elision.
See: https://github.com/jbcoe/CppSandbox/blob/master/ScopeGuard/ScopeGuard.cpp
for a similar class.
I ran cmake to generate a VS solution and built, and got a ton of generated files not ignored by .gitignore. Would be good to add these files.
Is there any reason to require CMake 3.2.2? I tried to lower it to 3.0.0 (version I have on my machine) and gsl was built and passed all tests. It probably can be built with even older versions.
I can send a PR to lower it for 3.0.0 for now.
I believed that this GSL library should use only standers ISO C++ following the C++ Core Guidelines.
I see things like
#ifdef _MSC_VER
__assume(ptr_ != nullptr);
#endif
Couldn't this be replaced by something else?
'array_view.h' uses tabs 'gsl.h' uses spaces. If my input matters I'd go with spaces :)
We can see the use of macros that can collide with the application macros as in
#if defined(SAFER_CPP_TESTING)
all the macros of the library must be prefixed by GUIDE_.
Because one of them is implicitly converted to T() causing a call to get()
array_view::as_array_view()
for byte arrays should either be restricted to types without alignment requirement or verify at runtime that the data pointer is properly aligned. Otherwise (according to The Standard) reinterpret_cast
may adjust the data pointer and I doubt this is the desired behaviour.
Currently the README says to clone https://github.com/Microsoft/unittest-cpp, which means a given SHA of GSL may produce different test results on different days if/as unittest-cpp gets new commits.
Two related questions then:
finally function heavily relies on rvo optimisation. If you compile with -fno-elide-constructor, you'll get util_tests errors
I think I understand why it is under Microsoft, but it feels weird. I think it would fit best directly beside https://github.com/isocpp/CppCoreGuidelines
Is this something that Microsoft would be okay transferring ownership over to the Standard C++ Foundation?
Cannot construct a maybe_null_dbg from an untested maybe_null_dbg, because get() is used in the copy constructor.
coordinate_facade has a static assert with the string: "ValueType must be unsigned integral type!", but it doesn't verify that ValueType is unsigned. If I change it to verify this it fails because array_view_tests use char.
struct ArrayViewTypeTraits<Traits, typename std::is_reference<typename Traits::array_view_traits &>::type>
std::is_reference<T>::type
isn't valid. It should be using std::is_reference<T>::value
.
AFAICS the docs are not completely self-contained. At least I was not able to find out within 30 minutes how and when to use the library. I looked at https://github.com/isocpp/CppCoreGuidelines and still did not catch the idea. Are there any short examples?
I grabbed some ideas from the unit tests, especially as_array_view
, but reading all unit tests to know about features like Expect
may be error prone because someone probably confuses test features with GSL features.
Any docs available beyond https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf ?
Another example: What is the semantics of maybe_null_dbg
? Cannot grab it from this test:
TEST(TestMaybeNull1)
{
int n = 5;
maybe_null_dbg<int *> opt_n(&n);
int result = 0;
bool threw = false;
CHECK_THROW(result = *opt_n, fail_fast);
}
This is inconsistent with not_null which allows this.
repro: maybe_null<std::nullptr_t>
Final_act(const Final_act&& other) : f_(other.f_) {}
Shouldn't that be:
Final_act(Final_act&& other) : f_(std::move(other.f_)) {}
The links provided in README.md to https://github.com/Microsoft/CppCoreGuidelines and Standard C++ Foundation (https://github.com/Microsoft/GSL/blob/master/isocpp.org) does not resolve. I couldn't find a repository named CppCoreGuidelines under the Microsoft organization (maybe it's private).
Considering the intent of Expects/Ensures to eventually be part of declarations, I can understand why they were made macros, but until a tool (or perhaps compiler extension, since I'm not sure it's possible to implement other than a namespace colliding macro?) actually supports placing them in a declaration, I think they would be better as functions.
As in the guidelines (ES.31), macros violate the usual scope rules, they can behave oddly with parameters, and they should be avoided unless necessary. Given this, I believe that as long as Ensures/Expects are being used in their current form, they would be better suited to functions.
for (int i = Bounds::rank - 2; i >= 0; --i)
stride[i] = stride[i + 1] * extents[i + 1];
Bounds::rank is a size_t, which can be incorrectly narrowed when converting to int.
Problem when using unsigned char:
array_view.h(495): const char dynamic_range = -1;
Problem when using signed char, many of the following:
array_view.h(xxxx): warning C4245: 'initializing': conversion from 'const char' to 'const size_t', signed/unsigned mismatch
I'm not too keen on disabling the related warnings...
It is a good practice to use an homogeneous naming convention. We find classes in lower_case and Lower_case as array_view and Final_act.
Most places in array_view.h
can do just fine with plain noexcept
even when testing with exceptions on.
It is usual to have the specific files of a library in a specific directory. I will suggest you to move them to include/Guide if this is the name of the library.
Build failed under my own Makefile exposing missing header (patch supplied)
The unites-cpp directory should be part of the main repository so that:
(1) git clone
(2) cmake configure
succeeds out of the box.
The text is leftover from an early implementation and is incorrect. The static_assert itself is correct.
This is a regression caused by my pull request #46. Can be reproduce by changing
template<class T> using maybe_null = maybe_null_ret<T>;
to maybe_null_dbg<T>;
and compiling. TestMaybeNullCasting will fail to compile.
For not_null<>, if there's a constructor for related types:
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
not_null(const not_null<U> &other);
I would also expect the assigment:
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
not_null<T> & operator=( not_null<U> const & other );
However it's not present.
Shouldn't it be Final_act(Final_act&& other)
so that it's a proper move constructor? Also shouldn't we std::move from other.f_ into f_?
The final_act
helper function function, finally
, is misleadingly named as it returns an object which, if not captured, will result in instant invocation of the given function object.
The following code looks correct but database lookups and insertions will fail as the 'final-act' was invoked at [1].
auto db_handle = my_db_api_open_db("My database name");
finally([db_handle]{ db_api_close_db(db_handle); }); // [1]
// do some lookups and insertions
I propose that finally
is renamed to make_final_act
or is replaced by a macro that captures the return value for the user into a uniquely named temporary variable (I prefer make_final_act
).
Since guidelines specify: "not_null ... T can be any type for which ==nullptr is meaningful." this should work
I added travis testing for gcc5 and clang36 on my fork
I'm ready to send in a PR if I got approval for this issue.
Let me know I need to add more compilers and which ones.
Guidelines Support Library shorthand "GSL" if will get widespread could be ambiguous in projects that use GNU Scientific Library (shorthand is GSL). Namespace gsl::
is used for some C++ wrappers for GNU Scientific Library. Same goes for macro prefixed with GSL_
.
Related to #9 #38
I know that people have different opinions about this, but in the design by contract community most people seem to adhere to this principle:
Use asserts for invariants, preconditions and postconditions. Use exceptions when user input is involved.
The purpose is to fail fast, and an assert is a way to fail faster since exceptions can be caught and hence worked around. People should never be able to work-around these invariants. If you fail to comply with the preconditions anything can happen (which I consider a good thing) and the implementations should not continue as if nothing happened.
If you follow this principle, Expects and Ensures should assert and not throw. It also means that you shouldn't put something in an not_null when it directly comes from the user (for example input data from a text file, something coming from an edit box, ...) since you are not sure that the precondition is fulfilled and hence it doesn't make sense to let not_null throw.
Some people also follow a slightly different variant: Use asserts for logic errors in your own code and exceptions when client code is involved. The different with the previous principle is that here the we are talking about client code and not user input. Since for example a not_null can be both used internally and at the border of the interface for the client you might want to use exceptions in for not_null when (and only when) client code is involved. In this case you might want to add a policy to these classes to be able to specify the desired fail behavior.
Anyway, since (some) people would like to be able to use these libraries without having exceptions, but have asserts instead, it makes sense to let the users to this library specify what should happen when the pre- and postconditions are not met. Next to the conceptual reasons there is also a performance reason. If the code is guaranteed not to throw more optimizations can be done.
A VC extension supported by other compilers for compatibility reasons.
There are places where we do
struct Foo {
...
};
And others where we do
struct Bar
{
...
};
We should pick one and stick with it.
owner alias as documented in https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md is not available in GSL. Isn't this supposed to be provided ?
Right now it's implemented like a smart pointer, with method like get(), but if I'm reading the isocpp guidelines correctly it should act like an alias. Given that it's under GSL.Views with owner
and not GSL.Owner with the smart pointers.
template <class T> using not_null = T;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.