Wednesday, February 14, 2018

Digest for comp.lang.c++@googlegroups.com - 12 updates in 3 topics

Nikki Locke <nikki@trumphurst.com>: Feb 14 11:23PM

Available C++ Libraries FAQ
 
URL: http://www.trumphurst.com/cpplibs/
 
This is a searchable list of libraries and utilities (both free
and commercial) available to C++ programmers.
 
If you know of a library which is not in the list, why not fill
in the form at http://www.trumphurst.com/cpplibs/cppsub.php
 
Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website.
Daniel <danielaparker@gmail.com>: Feb 14 02:43PM -0800

Is there a reason why
 
explicit
basic_string(std::basic_string_view<CharT, Traits> sv,
const Allocator& alloc=Allocator()); // (1)
 
is explicit, but
 
operator std::basic_string_view<CharT, Traits>() const noexcept;
 
is not?
 
I can't see a particular reason for making (1) explicit, considering
that the constructor that takes const CharT* s is not.
 
Thanks,
Daniel
wij@totalbb.net.tw: Feb 13 07:05PM -0800

On Wednesday, February 14, 2018 at 12:34:03 AM UTC+8, James R. Kuyper wrote:
> If you want sin2 to be an expression that points to the same function as
> ::sin, that's easy to arrange:
 
> auto const sin2 = ::sin;
 
What has presented is a (mis)reduced version of the real problem,
because the result is different from file to file, difficult to
reproduce (and I almost forgotten I can't expect the address of
inlined function be identical ,not by what the standard says but
by the semantics, or user's common understanding.
 
Actually, I were trying to wrap ::pow10 (manpage says this is a
GNU extension)
 
namespce Ns {
inline float pow10(float v) { return ::pow10f(v); };
inline double pow10(double v) { return ::pow10(v); };
inline long double pow10(long double v) { return ::pow10l(v); };
};
 
To keep things in topic, I tried evaluate
"auot const sin2=::sin;" in older style:
 
typedef float (& Math_f)(float);
typedef double (& Math_d)(double);
 
namespace Ns{
const Math_f pow10(::pow10f);
const Math_d pow10(::pow10);
};
 
But:
$g++ file.cpp
file.cpp: error: conflicting declaration 'double (& Ns::pow10)(double)'
const Math_d pow10(::pow10);
 
So, this problem is still hanging there!
Jorgen Grahn <grahn+nntp@snipabacken.se>: Feb 14 06:49AM

> On Wednesday, February 14, 2018 at 12:34:03 AM UTC+8, James R. Kuyper wrote:
...
 
> What has presented is a (mis)reduced version of the real problem,
 
Yes, I wondered what you really wanted to do.
 
> inline double pow10(double v) { return ::pow10(v); };
> inline long double pow10(long double v) { return ::pow10l(v); };
> };
 
[To non-Linux readers: these three GNU functions take a float, double
and long double respectively.]
 
Well, that code looks simple and correct to me. (Except I'm not sure
which overload is picked if you call Ns::pow10() with an int or
similar.)
 
I didn't have time to understand the rest (below) though. What do you
need it for?
 
> file.cpp: error: conflicting declaration 'double (& Ns::pow10)(double)'
> const Math_d pow10(::pow10);
 
> So, this problem is still hanging there!
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Ian Collins <ian-news@hotmail.com>: Feb 14 08:09PM +1300

> inline double pow10(double v) { return ::pow10(v); };
> inline long double pow10(long double v) { return ::pow10l(v); };
> };
 
Using inline, which is only a hint, is pretty pointless here. First off
the functions probably will be inlined and secondly even if they
weren't, the call overhead would be insignificant.
 
You will also hit ambiguity problems with calls like "pow10(2);" or
passing anything that isn't a floating point type.
 
Finally, loose all those superfluous semicolons!
 
--
Ian.
"James R. Kuyper" <jameskuyper@verizon.net>: Feb 14 08:50AM -0500

> On Wednesday, February 14, 2018 at 12:34:03 AM UTC+8, James R. Kuyper wrote:
...
> reproduce (and I almost forgotten I can't expect the address of
> inlined function be identical ,not by what the standard says but
> by the semantics, or user's common understanding.
 
That's true only of inline functions with internal linkage - a separate
actual definition of such a function will be created for each
translation unit in which you take it's address. However, "... An inline
function or variable with external linkage shall have the same address
in all translation units. ..." (10.1.6p6).
 
> $g++ file.cpp
> file.cpp: error: conflicting declaration 'double (& Ns::pow10)(double)'
> const Math_d pow10(::pow10);
 
The problem is that Ns::pow10 is a reference to a function, it's not
itself a function. As a result, it cannot be overloaded.
If you need overloading, you'll have to define wrapper functions, and
the wrapper functions will unavoidably have addresses (if you take their
addresses) even if inlined, that are different from the addresses of the
function they wrap. That's not a problem - calls to one of the wrappers
will still be inlined. And if the existence of the actual functions
wasting space bothers you, remove the code that takes the address of
those functions - then the compiler will have no need to create them.
wij@totalbb.net.tw: Feb 14 06:41AM -0800

On Wednesday, February 14, 2018 at 3:09:28 PM UTC+8, Ian Collins wrote:
 
> Using inline, which is only a hint, is pretty pointless here. First off
> the functions probably will be inlined and secondly even if they
> weren't, the call overhead would be insignificant.
 
These codes are in a header file. If definition is given and not inline,
complier would say multiple definition error.
 
> You will also hit ambiguity problems with calls like "pow10(2);" or
> passing anything that isn't a floating point type.

Is'nt that ambiguity problem for all kind of function overloads?
 
> Finally, loose all those superfluous semicolons!
For detecting language changes, at least.
wij@totalbb.net.tw: Feb 14 06:53AM -0800

On Wednesday, February 14, 2018 at 9:50:37 PM UTC+8, James R. Kuyper wrote:
> translation unit in which you take it's address. However, "... An inline
> function or variable with external linkage shall have the same address
> in all translation units. ..." (10.1.6p6).
 
How unfortunate!
 
> will still be inlined. And if the existence of the actual functions
> wasting space bothers you, remove the code that takes the address of
> those functions - then the compiler will have no need to create them.
 
I was surprised for a moment that such overloading problems can be
solved by reference overload. Probably future C++ might consider adding
such function reference overload.
"James R. Kuyper" <jameskuyper@verizon.net>: Feb 14 10:19AM -0500

> On Wednesday, February 14, 2018 at 3:09:28 PM UTC+8, Ian Collins wrote:
>> On 02/14/2018 04:05 PM, wij@totalbb.net.tw wrote:
...
>> weren't, the call overhead would be insignificant.
 
> These codes are in a header file. If definition is given and not inline,
> complier would say multiple definition error.
 
Actually, it's detected by the linker, not the compiler. At compile
time, there's only one definition. You don't have multiple definitions
until it's time for multiple translation units to be linked together. If
your compiler automatically invokes the linker, it can be difficult to
notice the distinction.
 
You can avoid that problem by giving them internal linkage. However,
many compilers (quite rightly) give you warnings if you declare a
function with internal linkage, but don't actually use it anywhere in
the same translation unit. That's because it's the only translation unit
where such a function could be used.
 
...
>> Finally, loose all those superfluous semicolons!
> For detecting language changes, at least.
 
Which language changes are you thinking of? A semicolon after a function
definition has always been superfluous, even back in C.
"James R. Kuyper" <jameskuyper@verizon.net>: Feb 14 10:20AM -0500

> On Wednesday, February 14, 2018 at 9:50:37 PM UTC+8, James R. Kuyper wrote:
>> On 02/13/2018 10:05 PM, wij@totalbb.net.tw wrote:
...
>> function or variable with external linkage shall have the same address
>> in all translation units. ..." (10.1.6p6).
 
> How unfortunate!
 
Why do you consider that unfortunate?
Paavo Helde <myfirstname@osa.pri.ee>: Feb 14 10:45PM +0200


>> You will also hit ambiguity problems with calls like "pow10(2);" or
>> passing anything that isn't a floating point type.
 
> Is'nt that ambiguity problem for all kind of function overloads?
 
No, if you provide enough overloads, or better yet, a template to take
care of any new primitive types added in the future:
 
namespace Ns {
inline float pow10(float v) { return ::pow10f(v); };
template<typename T> double pow10(T v) { return ::pow10(v); };
inline long double pow10(long double v) { return ::pow10l(v); };
}
Paavo Helde <myfirstname@osa.pri.ee>: Feb 14 11:02PM +0200

>>> inline double pow10(double v) { return ::pow10(v); };
>>> inline long double pow10(long double v) { return ::pow10l(v); };
>>> };
 
In addition, be warned that adding a function in a namespace with the
same name as a function in the global namespace is not a good idea,
especially if it takes the same number of arguments. Yes, you can make
that work, but it's still error-prone and you will lose some extra hair
because of this in the future ;-)
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: