Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by conistonwater on Saturday October 10, 2015 @02:52PM
(#10366515)
Not touching on the rest of what you said, but what's so bad about min? Apart from some internal clang stuff, like odd names and macros, it looks okay - I can see what the function is doing.
// min
template <class _Tp, class _Compare>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const _Tp&
min(const _Tp& __a, const _Tp& __b, _Compare __comp)
{
return __comp(__b, __a) ? __b : __a;
}
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const _Tp&
min(const _Tp& __a, const _Tp& __b)
{
return _VSTD::min(__a, __b, __less<_Tp>());
}
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
template<class _Tp, class _Compare>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_Tp
min(initializer_list<_Tp> __t, _Compare __comp)
{
return *__min_element(__t.begin(), __t.end(), __comp);
}
template<class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_Tp
min(initializer_list<_Tp> __t)
{
return *__min_element(__t.begin(), __t.end(), __less<_Tp>());
}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by Animats on Saturday October 10, 2015 @03:08PM
(#10366575)
It used to be
#define min(x,y) ((x) < (y) ? (x) : (y))
Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by vbernat on Saturday October 10, 2015 @06:13PM
(#10367194)
Better use:
#define min(X, Y) \
({ typeof (X) x_ = (X); \
typeof (Y) y_ = (Y); \
(x_ < y_) ? x_ : y_; })
Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by pjmlp on Saturday October 10, 2015 @04:13PM
(#10366820)
Which is anything but safe.
Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by azinman2 on Saturday October 10, 2015 @05:52PM
(#10367140)
Can you explain more please?
Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by copascetic on Saturday October 10, 2015 @06:08PM
(#10367180)
Because a macro in C/C++ is just text expansion, the given implementation will evaluate its arguments more than once, which will not be obvious at the "call" site and could have unintended consequences if the expressions have side-effects.
Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by azinman2 on Tuesday October 13, 2015 @01:58AM
(#10378760)
Is there another way to do it as a macro that avoids this? How do you have temporary variables potentially in the middle of a larger expression, e.g. if (min(a,b) == 3) {...}
Re:Emulating Swift's “defer” in C, with Clang or GCC+Blocks
by duaneb on Saturday October 10, 2015 @04:39PM
(#10366908)
I think I just see it as different niches. C++ only adds to the code after a certain amount of complexity because there is so much magic its hard to manually translate to assembly in your head (at times). I certainly don't know much about c++ >03; the additions have been.... Probably not worth using over c for the massive probability and ability to contribute easily for small tools.
C++ templates are Turing-complete. You can do arbitrary computation at compile time. Once this was discovered, ever-fancier templates became a basic part of C++. (Take a look at the huge templates that implement "max" and "min".) Then the C++ standards committee went off into template la-la land, focusing on adding features to make the template system more powerful. After a decade of this, many standard templates are now at the "you are not supposed to understand this" level.
This has scared people off of C++, which is why there's still much work in standard C. So now we're seeing features added to C to solve specific problems, but without an architecture.
"Defer" is troublesome, because dealing with errors in deferred statements is hard. C++ has the same problem with destructors. A "with" clause, which LISP introduce as "with-open-file" and Python also supports, is a better way to do this. Python's combination of "with" and exception handling can handle an error when closing out a resource, and get all the nested resources closed out properly. Few other languages even try to get that right.