Thursday, March 9, 2023

Digest for comp.lang.c++@googlegroups.com - 25 updates in 5 topics

Jivanmukta <jivanmukta@poczta.onet.pl>: Mar 09 11:18AM +0100

When I run my program is VSCode, it shows:
 
Loaded '/lib/x86_64-linux-gnu/libstdc++.so.6'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libm.so.6'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libgcc_s.so.1'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libc.so.6'. Symbols loaded.
 
Program received signal SIGSEGV, Segmentation fault.
0x0000000000428172 in
__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::vector<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >::__normal_iterator
(this=0x7fffffffca60, __i=<error reading variable>) at
/usr/include/c++/9/bits/stl_iterator.h:804
804 : _M_current(__i) { }
Execute debugger commands using "-exec <command>", for example "-exec
info registers" will list registers in use (when GDB is the debugger)
 
 
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
// This iterator adapter is @a normal in the sense that it does not
// change the semantics of any of the operators of its iterator
// parameter. Its primary purpose is to convert an iterator that is
// not a class, e.g. a pointer, into an iterator that is a class.
// The _Container parameter exists solely so that different containers
// using this template can instantiate different types, even if the
// _Iterator parameter is the same.
using std::iterator_traits;
using std::iterator;
template<typename _Iterator, typename _Container>
class __normal_iterator
{
protected:
_Iterator _M_current;
 
typedef iterator_traits<_Iterator> __traits_type;
 
public:
typedef _Iterator iterator_type;
typedef typename __traits_type::iterator_category iterator_category;
typedef typename __traits_type::value_type value_type;
typedef typename __traits_type::difference_type difference_type;
typedef typename __traits_type::reference reference;
typedef typename __traits_type::pointer pointer;
 
_GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT
: _M_current(_Iterator()) { }
 
explicit
__normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT
: _M_current(__i) { } // !!! HERE PROBLEM !!!
Paavo Helde <eesnimi@osa.pri.ee>: Mar 09 02:11PM +0200

09.03.2023 12:18 Jivanmukta kirjutas:
> Loaded '/lib/x86_64-linux-gnu/libgcc_s.so.1'. Symbols loaded.
> Loaded '/lib/x86_64-linux-gnu/libc.so.6'. Symbols loaded.
 
> Program received signal SIGSEGV, Segmentation fault.
 
The problem is in your code, find and fix it.
 
To help with that, you might want to enable the g++ STL debugging
features, by compiling all your C++ code with -D_GLIBCXX_DEBUG
Jivanmukta <jivanmukta@poczta.onet.pl>: Mar 09 05:03PM +0100

W dniu 9.03.2023 o 13:11, Paavo Helde pisze:
 
> The problem is in your code, find and fix it.
 
> To help with that, you might want to enable the g++ STL debugging
> features, by compiling all your C++ code with -D_GLIBCXX_DEBUG
 
I have a problem when debugging.
 
TRACE("before insert");
identifiers[what].insert(identifiers[what].end(),
ids.begin(), ids.end());
 
TRACE is executed then SIGSEGV although I have a breakpoint at line with
insert.
scott@slp53.sl.home (Scott Lurndal): Mar 09 04:44PM

>ids.begin(), ids.end());
 
>TRACE is executed then SIGSEGV although I have a breakpoint at line with
>insert.
 
Show your work What does the 'bt' command show? What does the
'info registers' command show? What does "x/i $pc" show?
Jivanmukta <jivanmukta@poczta.onet.pl>: Mar 09 06:12PM +0100

W dniu 9.03.2023 o 17:44, Scott Lurndal pisze:
>> insert.
 
> Show your work What does the 'bt' command show? What does the
> 'info registers' command show? What does "x/i $pc" show?
I cannot see these. When I click Debugging Console tab I receive SIGSEGV
undepending where I have set a breakpoint.
I also have SIGSEGV after TRACE when I run my application from command
prompt, not VSCode.
Jivanmukta <jivanmukta@poczta.onet.pl>: Mar 09 06:35PM +0100

W dniu 9.03.2023 o 18:12, Jivanmukta pisze:
> undepending where I have set a breakpoint.
> I also have SIGSEGV after TRACE when I run my application from command
> prompt, not VSCode.
 
Could it be hardware problem, not with my application?
Sam <sam@email-scan.com>: Mar 08 07:39PM -0500


> >It only knows what's thrown at runtime. Not at compile time. It is
 
> It knows what is thrown at runtime.
> It knows what *could* be thrown at compile time.
 
No, it doesn't. If foo() calls bar() from another translation unit, there's
no information available to compiler to indicate what bar() could possibly
throw.
 
One of the biggest C++ design fuckups was the screwed up throw-specifiers,
that basically meant nothing useful, and they're now completely gone.
 
C++ should've handled throw specifiers the same way Java does, making it
possible to guarantee /at compile time/ that all exceptions get handled,
 
> encompassing
> those throws then it could compile in suitable types for an auto in the
> catch.
 
I'll write the bar(), you write the foo(), and we'll see if you know what
I'm throwing.
Muttley@dastardlyhq.com: Mar 09 09:12AM

On Wed, 08 Mar 2023 19:39:11 -0500
>> catch.
 
>I'll write the bar(), you write the foo(), and we'll see if you know what
>I'm throwing.
 
Once something is thrown the runtime knows what it is and simply has to
match it with a catch as it does now. I'm not pretending matching an auto
would be simple but I don't see why it should be impossible. After all, the
runtime has to differentiate between int, char, parent and child classes to
do proper catching.
Muttley@dastardlyhq.com: Mar 09 09:13AM

On Wed, 8 Mar 2023 18:28:32 +0100
>along to verify if it fits against the type being catched.
>If you want to catch sth. auto-ish you won't have a strong
>type-match. So this doesn't work.
 
Does it need to be a strong match? If the runtime knows a pair has been
thrown - and it must or it couldn't be caught at all - then why can't it
do a match to see if an auto matches? Yes it'll be more complex than the
current system but I don't see why it would be impossible.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 09 10:16AM +0100


> Once something is thrown the runtime knows what it is and simply has to
> match it with a catch as it does now. I'm not pretending matching an auto
> would be simple but I don't see why it should be impossible. ...
 
It is impossible since the code inside the catch-block could have
different unrelated types.
"Öö Tiib" <ootiib@hot.ee>: Mar 09 03:18AM -0800

> thrown - and it must or it couldn't be caught at all - then why can't it
> do a match to see if an auto matches? Yes it'll be more complex than the
> current system but I don't see why it would be impossible.
 
Sam writes a function bar() that has switch case in it that throws
different objects from long list of struct {? a; ? b;} , std::array<?,2>, std::tuple<?,?>,
std::pair<?, ?>, etc. Each case different types in places of those
question marks. What do your str and val bind to in your foo() that calls
that bar()?
Paavo Helde <eesnimi@osa.pri.ee>: Mar 09 02:06PM +0200

> would be simple but I don't see why it should be impossible. After all, the
> runtime has to differentiate between int, char, parent and child classes to
> do proper catching.
 
Yes, and it generates code for handling them at compile time, for the
types which are explicitly specified in the catch clause.
 
If one wants to support catch handlers which catch any "templated" type,
one would need to generate catch handler code for all types present in
the program. This would need at least link-time code generation and
could easily produce catch handler code many times larger than the rest
of the program.
 
If the program uses dynamic libraries, link-time code generation would
not be sufficient. One would need to generate code at run time. This is
not something what is commonly done in C++. And what happens if it
appears the "template" cannot be instantiated for these new types? You
would get a compile error at run time. Ugh... that would not be C++ any
more.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 09 05:06PM +0100


> Does it need to be a strong match? ...
 
With what you've shown it would be impossible to determine the types of
the bindings. And structured binding further wouldn't make sense because
no one wants to throw non-opaque types; all exceptions I use are opaque
and dont have directly acessible data members.
David Brown <david.brown@hesbynett.no>: Mar 09 12:59AM +0100

On 08/03/2023 23:29, Keith Thompson wrote:
 
> Again, I didn't intend to concentrate on the case of signed integer
> overflow. My question was about which cases of undefined behavior
> could be made into defined behavior without adding runtime checks.
 
It is also perhaps worth noting that if signed integer overflow is left
undefined, some optimisations are possible for the compiler that are not
if overflow is required to be wrapping. That might not qualify as
"run-time checks", but it is certainly "run-time overhead" in comparison
to the current language definition.
David Brown <david.brown@hesbynett.no>: Mar 09 01:08AM +0100

On 08/03/2023 21:48, Michael S wrote:
>> likely to be *useful*.
 
> My favorite example of usefulness of wrapping signed overflow behavior
> is CIC (a.k.a. Hogenauer) interpolation and decimation filters.
 
I think that still counts as "not likely to be useful". Yes, two's
complement wrapping on overflow is /occasionally/ useful, but only very
occasionally. And for many DSP algorithms, saturation would be much
more helpful than wrapping.
 
Overflow of fixed-size integers will, in general, give the wrong answer
- no matter how it is defined. Therefore, there is no point in defining
it to have a particular choice of wrong behaviour, to the detriment of
other aspects (such as optimisation, or the freedom for tools or
sanitizers to temporarily add run-time checks for debugging). Whatever
you do, some basic laws of normal mathematical integer arithmetic will
have to be broken - having the overflow behaviour left undefined
actually keeps more of them, and more useful laws (such as "x + 1 > x"
for any "x") than defined behaviours.
 
If there had to be one single defined behaviour, then saturation is the
only reasonable one. If you have a marble jar, and keep adding marbles,
it will reach a limit - try to add more, and you will still have the
same number of marbles in the jar (and more on the floor). It would be
mind-bogglingly insane to suggest that adding one more marble to a full
jar would give you a negative jarful of marbles.
David Brown <david.brown@hesbynett.no>: Mar 09 01:12AM +0100

On 08/03/2023 22:40, Alf P. Steinbach wrote:
> type return value, so as to not cause inadvertent wrapping problems in
> comparisons and arithmetic involving negative signed type values.
 
> So it's a bit about safety, of being able to choose signed type freely.
 
Wrapping /can/ occasionally be useful (this kind of things is one such
case). Fortunately, there's an easy answer, even if the timers are
signed values - convert to unsigned, do the subtraction, convert back to
signed (if you want). That is all well-defined behaviour (albeit
partially implementation-dependent).
 
 
As a bit of trivia, Windows 95 had a bug that caused it to crash as soon
as that millisecond counter rolled over. The OS had been out for over
ten years before the bug was noticed - apparently no one had managed to
keep a Windows 95 system running for 49 days without it crashing for
some other reason!
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Mar 08 04:27PM -0800

David Brown <david.brown@hesbynett.no> writes:
[...]
> over ten years before the bug was noticed - apparently no one had
> managed to keep a Windows 95 system running for 49 days without it
> crashing for some other reason!
 
Or, perhaps more likely, nobody who had a Windows 95 system crash after
49 days ever figured out why it had crashed.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */
Malcolm McLean <malcolm.arthur.mclean@gmail.com>: Mar 09 02:08AM -0800

On Thursday, 9 March 2023 at 00:09:04 UTC, David Brown wrote:
> same number of marbles in the jar (and more on the floor). It would be
> mind-bogglingly insane to suggest that adding one more marble to a full
> jar would give you a negative jarful of marbles.
 
It makes it easy to put in a check.
 
int marbles = N;
marbles++;
if (marbles < 0)
/* This can't happen so we've overflowed. Take action. */
 
If you saturate, then you have to either put the test in before you do the calculation,
which will work for marbles++, but gets more difficult for marbles += N; or you have
to say that INT_MAX is an error value for the number of marbles. This is a headache
for anyone maintaining the code, as naturally they expect that the number of
marbles can go from 0 to INT_MAX inclusive.
"Öö Tiib" <ootiib@hot.ee>: Mar 09 03:03AM -0800

On Wednesday, 8 March 2023 at 19:53:09 UTC+2, Keith Thompson wrote:
 
> I'd be interested in seeing some cases of undefined behavior that could
> reasonably be detected at compile time or at run time. I'm sure there
> are some, but I'd be surprised it were as many as half.
 
There are lot of low hanging undefined or unspecified behavior. Even what
I've open at the moment. <https://en.cppreference.com/w/cpp/io/c/FILE>
"While it may be possible to copy a valid std::FILE, using a pointer to such
a copy as an argument for an I/O function invokes unspecified behavior."
Such situation made sense maybe at 1998 ... at 2023 can require that
copying std::FILE is compiling error.
 
> Just one example: Signed integer overflow has undefined behavior, and
> defining it would require runtime checks.
 
Ideally such run-time checks will cost something only at hardware level
or when failing.
 
So when programming languages require checks then hardware guys have
market for putting those in.
 
Unfortunately the wannabe "better C++s" tend to choose wrap around
instead of failure on case of signed overflow. Wrap around is what
hardware already does but it makes very rarely sense. For most
programs an integer overflow is error like division by zero.
I would just add something for example "_Unsafe int" and
"_Wrapping int" for those who want signed int to have undefined
behavior or wrap around.
David Brown <david.brown@hesbynett.no>: Mar 09 01:52PM +0100

On 09/03/2023 01:27, Keith Thompson wrote:
>> crashing for some other reason!
 
> Or, perhaps more likely, nobody who had a Windows 95 system crash after
> 49 days ever figured out why it had crashed.
 
You are spoiling a good legend with realism! :-)
David Brown <david.brown@hesbynett.no>: Mar 09 02:06PM +0100

On 09/03/2023 11:08, Malcolm McLean wrote:
> to say that INT_MAX is an error value for the number of marbles. This is a headache
> for anyone maintaining the code, as naturally they expect that the number of
> marbles can go from 0 to INT_MAX inclusive.
 
I think a "look /before/ you leap" attitude is to be encouraged in
programming - rather than jump first and see what you can learn from the
post-mortem.
 
if (marbles < INT_MAX) {
marbles++;
} else {
// No room to proceed
}
 
or for gcc fans:
 
int m;
if (__builtin_add_overflow(marbles, 1, &m)) {
handle_overflow();
} else {
marbles = m;
}
Bonita Montero <Bonita.Montero@gmail.com>: Mar 09 03:26PM +0100

Am 07.03.2023 um 22:38 schrieb Lynn McGuire:
> efforts to move it forward are ongoing both inside the ISO C++ steering
> committee as well as other projects."
 
> Lynn
 
Read this:
https://mega.nz/file/ehcR1S5B#5YcRMdcJ0WArshD0szI2bckaqVmk2jC59XmOZh_GXgM
Malcolm McLean <malcolm.arthur.mclean@gmail.com>: Mar 09 07:14AM -0800

On Thursday, 9 March 2023 at 13:06:18 UTC, David Brown wrote:
 
> I think a "look /before/ you leap" attitude is to be encouraged in
> programming - rather than jump first and see what you can learn from the
> post-mortem.
 
In which case you can say that signed integer arithmetic has undefined behaviour,
because you catch the overflow before you do the calculation. Which is in fact
the current situation. One benefit of defining the behaviour is so that you can do
it post mortem. The other benefit is that if overflow isn''t handled correctly, the bug
is consistent.
 
> } else {
> // No room to proceed
> }
 
That's how you've got to do it currently. Depending on the flow control, in actual code
it may be more or less difficult to understand than doing the test after the increment.
Defining the behaviour on overflow doesn't prevent you doing it your way, but it gives
you another option.
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Mar 09 03:18AM -0800

Yesterday, I wrote:
 
> Hacking alone won't cut the mustard on this occasion, I need divine inspiration.
 
 
I have this working now. Here's what I did:
 
Step 1: Link statically with the wxWidgets libraries, and don't link dynamically with the other libraries such as gdk, pango and cairo.
 
So where you would normally have the following in the Makefile:
$(shell wx-config --libs all)
Replace it with:
$(shell wx-config --libs all | tr ' ' '\n' | grep "\.a$$" | tr '\n' ' ')
 
Step 2: Allow unresolved symbols in the final executable file, list all symbols, and link lazily:
-Wl,--unresolved-symbols=ignore-in-object-files,--export-dynamic,-z,lazy
 
Step 3: Write thunks for the two functions whose address is required at runtime (there's only two of them):
 
gboolean gtk_true(void)
{
static gboolean (*const p)(void) = reinterpret_cast<gboolean(*)(void)>( dlsym(RTLD_NEXT, "gtk_true") );
 
return p();
}
 
void gtk_main_do_event(GdkEvent *const arg)
{
static void (*const p)(GdkEvent*) = reinterpret_cast<void(*)(GdkEvent*)>( dlsym(RTLD_NEXT, "gtk_main_do_event") );
 
p(arg);
}
 
Step 4: In main, if you need to use the GUI, then load the GUI libraries:
 
int main(int argc, char **argv)
{
// Before main has been entered, we had:
// pre_start -> _start -> _libc_start_main -> main
 
if ( argc < 2 )
{
Load_GUI_Libraries();
return wxEntry(argc, argv);
}
 
cout << "This is the console program :-)" << endl;
}
 
And finally here's the function for loading the GUI libraries at runtime:
 
char const *const g_strs_dyn_libs[] = {
"libpng16.so.16",
"libfontconfig.so.1",
"libglib-2.0.so.0",
"libgobject-2.0.so.0",
"libpango-1.0.so.0",
"libpangoft2-1.0.so.0",
"libgio-2.0.so.0",
"libgdk_pixbuf-2.0.so.0",
"libcairo.so.2",
"libpangocairo-1.0.so.0",
"libgdk-3.so.0",
"libgtk-3.so.0",
"libSM.so.6",
"libX11.so.6",
nullptr
};
 
void Load_GUI_Libraries(void)
{
using std::cerr; using std::endl;
 
for ( char const *const *pp = g_strs_dyn_libs; nullptr != *pp; ++pp )
{
if ( nullptr == dlopen(*pp, RTLD_LAZY | RTLD_GLOBAL) )
{
cerr << "ERROR loading library: " << *pp << endl;
std::abort();
}
}
}
 
So now I have an executable file that can run in two modes:
(1) GUI mode - it loads the GUI libraries in 'main'
(2) Console mode - it never loads the GUI libraries
 
Most importantly - the console mode can run on PC's that don't have the GUI libraries installed.
 
They're talking about making a movie about my endeavours to get his working, "I Am Legend". I'm not black but Will Smith just wowed them all in the audition so I promptly approved his appointment to play my role.
MarioCPPP <NoliMihiFrangereMentulam@libero.it>: Mar 09 02:19AM +0100

> #include <string>
 
> using namespace std;
 
> void myfunc(string &s1)
^^^
does not seem that "string && s1" that I was asking about,
though ....
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
MarioCPPP
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: