Friday, December 18, 2020

Digest for comp.lang.c++@googlegroups.com - 13 updates in 4 topics

Vir Campestris <vir.campestris@invalid.invalid>: Dec 18 11:13AM

So I have a header file with some templated code in it. This is a
simplified version
 
template <typename T> void func() {
std::cout << "in " << __PRETTY_FUNCTION__ << std::endl;
method(T());
std::cout << "leaving " << __PRETTY_FUNCTION__ << std::endl;
}
 
You'll notice it calls "method".
 
I also have a couple of cpp files, which use the template
 
#include <iostream>
 
template <typename T> void method(const T & param) {
std::cout << "In method a " << __PRETTY_FUNCTION__ << std::endl;
}
 
#include "template.h"
 
void a() {
func<int>();
}
 
they're identical, except in the second one the function at the bottom
is called b, and the message in method says "In method b".
 
From another file I call a and b.
 
The messages indicate that BOTH calls to a and b call the same method()
function.
 
This is because the instantiated template function from both a.cpp and
b.cpp have the same signature, so the linker throws one of them away.
 
It took me a while to track it down in the real code.
 
Andy
Richard Damon <Richard@Damon-Family.org>: Dec 18 08:05AM -0500

On 12/18/20 6:13 AM, Vir Campestris wrote:
> b.cpp have the same signature, so the linker throws one of them away.
 
> It took me a while to track it down in the real code.
 
> Andy
 
Doesn't seem that surprising to me. You named two different functions
with the same name so you should expect an issue. Now, being templates,
the system is more apt to not detect the problem and report the issue.
 
There is a similar issue with just plain global variables, which gcc
just recently changed the behavior from ignoring to reporting and a lot
of people are being caught unawares that it was a problem.
"Öö Tiib" <ootiib@hot.ee>: Dec 18 08:52AM -0800

On Friday, 18 December 2020 at 13:13:36 UTC+2, Vir Campestris wrote:

> This is because the instantiated template function from both a.cpp and
> b.cpp have the same signature, so the linker throws one of them away.
 
> It took me a while to track it down in the real code.
 
Yes some violations of ODR are required to be detected by standard but
others are that your program is ill formed but no diagnostic is required.
 
Both the patterns "undefined behavior" and "no diagnostic is required"
are massively represented in C++ standard so it will take years to
learn to avoid those in your own code and even more years to notice
in code of others. But committee releases more every 3 years so the
process of learning C++ should be continuous.
Vir Campestris <vir.campestris@invalid.invalid>: Dec 18 09:43PM

On 18/12/2020 13:05, Richard Damon wrote:
> Doesn't seem that surprising to me. You named two different functions
> with the same name so you should expect an issue. Now, being templates,
> the system is more apt to not detect the problem and report the issue.
 
If I named two different ordinary functions the same I'd expect the
linker to object.
 
With template instantiations it optimises one away - based purely on the
signature, not the content. I suppose it would be too hard to check the
content.
 
> There is a similar issue with just plain global variables, which gcc
> just recently changed the behavior from ignoring to reporting and a lot
> of people are being caught unawares that it was a problem.
 
I don't think I follow you.
 
Andy
Richard Damon <Richard@Damon-Family.org>: Dec 18 06:18PM -0500

On 12/18/20 4:43 PM, Vir Campestris wrote:
>> of people are being caught unawares that it was a problem.
 
> I don't think I follow you.
 
> Andy
 
 
GCC has long allowed multiple translation units to define variables by
the same name as globals (and not require that all but one be declared
as extern to make them just declarations and not definitions). It did
not check that they ware of the same type, but just put all of them at
the same memory location.
 
Defining globals by the same name in different translation units is
undefined behavior (whether a function of a variable), but does not
require a diagnostic.
 
GCC has had an option that would flag this case as an error, but the
default has been until a very recent version, to allow this to happen
(for variables) by default. The recent version has changed the default
to generate an error, and some programming communities are having fits
due to this, as long working programs are now not building.
 
The function issue brought up is very much of the same sort of thing.
Normal functions will generate duplicate definition errors if you define
the same function in two translation units. Due to code generation
issues with templates, template functions are normally compiled so that
multiple copies get merged into a single version, from one of the
translation units.
Brian Wood <woodbrian77@gmail.com>: Dec 18 06:35AM -0800

On Saturday, January 28, 2017 at 11:31:25 AM UTC-6, Brian Wood wrote:
> If you mean there are costs for standard library implementors
> and to compile times, I agree. But I don't think there's
> a run-time cost for adding that function if you don't use it.
 
I wish this would have been added to 2020 C++. Perhaps it's
not too late for the next version.
 
 
Brian
Ebenezer Enterprises - In G-d we trust.
https://webEbenezer.net
Bonita Montero <Bonita.Montero@gmail.com>: Dec 18 04:25PM +0100

What's wrong with the static address ::what() returns ?
Bonita Montero <Bonita.Montero@gmail.com>: Dec 18 04:32PM +0100

> Why pay for what you don't need?
> If you have a std::string, and a lot of people do, you can avoid
> throwing away the length by using string_view rather than char*.
 
string_view is for integrating native memory ranges of characters
with the string-facilities so that you can peformantly combine them
with the usual string-facilities. But exceptions are very slow anyway.
So I don't see any sense other than exception::what() to return like
a normal C-string.
"Öö Tiib" <ootiib@hot.ee>: Dec 18 09:17AM -0800

> > a run-time cost for adding that function if you don't use it.
 
> I wish this would have been added to 2020 C++. Perhaps it's
> not too late for the next version.
 
What the what() returns is either ignored or conditionally streamed
to some kind of log in most code bases I've observed. The
string_view does not boost performance of neither operation.
Adding another virtual method to get string_view out of exception
would therefore just make binary larger as compilers can optimize
virtual calls into non-virtual or even inline those but that is not done
with caught exceptions. Also compilers do not optimize away virtual
table entries and code of such entries of used classes AFAIK.
Brian Wood <woodbrian77@gmail.com>: Dec 18 10:32AM -0800

On Friday, December 18, 2020 at 11:18:18 AM UTC-6, Öö Tiib wrote:
> What the what() returns is either ignored or conditionally streamed
> to some kind of log in most code bases I've observed. The
> string_view does not boost performance of neither operation.
 
It's true that syslog and some other loggers can't handle
string_view, but by the grace of G-d we are getting some C++-based
operating systems. I haven't looked at them in much depth, but
I hope they will use string_view in their APIs.
 
> virtual calls into non-virtual or even inline those but that is not done
> with caught exceptions. Also compilers do not optimize away virtual
> table entries and code of such entries of used classes AFAIK.
 
How about if you use link-time optimization? Probably
static exceptions will affect some of the things you mention.
 
 
Brian
Ebenezer Enterprises
"Öö Tiib" <ootiib@hot.ee>: Dec 18 07:24AM -0800

> > fine, and IMHO clearer than lambdas.
 
> I was wondering if they would be a clearer or shorter way to do
> it, but agree they aren't in this case. Thanks for posting all of that.
 
Why you were wondering?
 
Lambdas are more sophisticated callables than functions as these can be defined
inline with other code, can capture state or references to state of place of
definition and do remove problems with passing and returning callables.
For example function can't be made to return function pointer of its own type.
 
The added flexibility also comes with additional boiler-plate, issues and
inconveniences. Otherwise the lambdas would obsolete functions. For
example recursive generic variadic lambdas are annoying to make.
 
As you apparently needed none of benefits of lambdas but instead wanted
to use weakness of those it is just interesting as exercise but lacks practical
value.
David Brown <david.brown@hesbynett.no>: Dec 18 04:59PM +0100

On 18/12/2020 16:24, Öö Tiib wrote:
 
> As you apparently needed none of benefits of lambdas but instead wanted
> to use weakness of those it is just interesting as exercise but lacks practical
> value.
 
That's what I thought when I tried it. Now I know how to make recursive
lambdas, which I did not know before trying it. (The trick is not
entirely unlike the CRTP.)
 
I don't know of a good use for this sort of thing - given that recursive
template functions are simpler - but it was more fun than the rest of
this thread.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Dec 17 07:53PM -0800

On 12/17/2020 12:24 PM, Bonita Montero wrote:
>> They were not standard. ...
 
> When you are bound to gcc only
 
I used GCC, but was not bound to it.
 
 
 
you could use these intrinsics portably
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: