- "C++ on the Move" by Darryl K. Taft - 5 Updates
- Simulating Halt Decider (SHD) Copyright (c) 2022 Mr Flibble - 1 Update
- SIGSEGV in stl_iterator.h - 6 Updates
- Why no structured bings in catch()? - 1 Update
David Brown <david.brown@hesbynett.no>: Mar 09 08:32PM +0100 On 09/03/2023 16:14, Malcolm McLean wrote: > 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. No, signed integer arithmetic has /defined/ behaviour - it is only /overflow/ that has undefined behaviour. > 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. Consistent bugs are not necessarily better (or rather, less bad) than inconsistent bugs. It can be helpful if a bug gives a consistent detectable issue that point to the cause - but equally a consistent bug could consistently hide the issue and lead you to look elsewhere for the problem. The idea that consistent incorrect behaviour is better than undefined behaviour is no more than a myth. > 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. It gives a /worse/ option that encourages bad programming habits. Do not write code that is broken, and gets things wrong - no matter what happens afterwards. (Note that this is very different from exceptions in C++, where throwing an exception is part of the defined and intentional behaviour of the code.) But no, the snippet above is /not/ the way you want to handle things normally. If you are checking for overflow like this, the chances are that your code is badly designed in the first place. (There are always exceptions and unusual cases.) You've got to ask yourself /why/ someone might be trying to add a marble to a full jar in the first place, and work backwards - somewhere in the earlier code there is likely to be poorly designed code. Maybe there are too many marbles involved, or the jar should be bigger, but something is probably wrong. At the very least, the code should be : if (marbles < jar_size) { marbles++; } else { // The jar is full - maybe it is time to empty it } In real code, the jar would never be INT_MAX in size - thus post-mortem checks for wrapping overflow cannot be used even if the language defined integer arithmetic that way. Overflows are bugs - but not necessarily in the bit of code they appear to be in. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Mar 09 12:12PM -0800 > 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. FILE is defined in the C standard library. The C standard says: The address of the FILE object used to control a stream may be significant; a copy of a FILE object need not serve in place of the original. which means that the behavior of passing a pointer to a copied FILE object to a library function is implicitly undefined. (I'm not sure why cppreference says the behavior is unspecified.) C *can't* make copying a FILE object illegal. A C++ library implementation could implement its own FILE type as a wrapper around the C FILE type and prohibit copying it, but then passing a C++ FILE* pointer to a C function that expects a C FILE* pointer would be awkward at best. Maybe you could define implicit conversions (I'm not sure whether that's even possible), but covering all the cases would be difficult. And I don't think it would even be worth the effort. FILE is treated as an opaque type. That opacity isn't enforced, but I've never seen C or C++ code that copies or even defines a FILE object. Real code just uses FILE* pointers. It's a very minor corner case. If I wanted to provide definitions for as much undefined behavior as possible, copying FILE objects would be very low on my list. >> defining it would require runtime checks. > Ideally such run-time checks will cost something only at hardware level > or when failing. Ideally, sure. > 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. First you have to define what you mean by "failure". Do you want evaluating INT_MAX+1 to abort the program? Throw an exception? Emit nasal demons? We're stuck with hardware with wraparound behavior for the foreseeable future. Conceivably if C and C++ started requiring trapping on signed overflow, hardware would gradually be updated to make that more efficient, but we wouldn't see the effects for decades. -- 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 */ |
Michael S <already5chosen@yahoo.com>: Mar 09 12:42PM -0800 On Thursday, March 9, 2023 at 2:09:04 AM UTC+2, David Brown wrote: > 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 CIC filters are just one example of very common pattern where even number of integer overflows compensate each other, producing correct final result. What is special in the case of CIC is that the number of overflows can be quite large. In more common case there are exactly two overflows compensating each other, most typically in expression like y1 = y0 + x1 - x0. > And for many DSP algorithms, saturation would be much > more helpful than wrapping. I did quite a lot of fix-point digital signal processing in the past. In my personal experience saturated arithmeticis pretty much never useful. What is useful, occasionally, is saturating conversion of wider signed type into narrower signed type. > for any "x") than defined behaviours. > If there had to be one single defined behaviour, then saturation is the > only reasonable one. Absolutely not! Saturation is non-associative, that's enough to take it out of consideration for default behavior. > 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. Somehow, you don't consider almost the same case insane for unsigned integers. |
Michael S <already5chosen@yahoo.com>: Mar 09 12:47PM -0800 On Thursday, March 9, 2023 at 2:52:42 PM UTC+2, David Brown wrote: > > 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! :-) Your story was unrealistic to begin with. Win95 was hardly used by anybody 5 years after its introduction, much less so 10 years after introduction. Win98, esp. Win98 SE, was simply better choice in almost any imaginable situation. |
Lynn McGuire <lynnmcguire5@gmail.com>: Mar 09 04:59PM -0600 On 3/9/2023 8:26 AM, Bonita Montero wrote: >> Lynn > Read this: > https://mega.nz/file/ehcR1S5B#5YcRMdcJ0WArshD0szI2bckaqVmk2jC59XmOZh_GXgM No freaking way. Looks like a ransomware file to me. Lynn |
olcott <polcott2@gmail.com>: Mar 09 02:31PM -0600 On 10/24/2022 1:19 PM, Mr Flibble wrote: > 3) Decider rejects pathological input as invalid by signaling sNaP. > https://github.com/i42output/halting-problem#readme > /Flibble I created the notion of a simulating halt decider in this forum On 3/14/2017 at 9:05 AM Message-ID: <e18ff0a9-7f9d-4799-9d13-55d021afaa82@googlegroups.com> -- Copyright 2023 Olcott "Talent hits a target no one else can hit; Genius hits a target no one else can see." Arthur Schopenhauer |
Jivanmukta <jivanmukta@poczta.onet.pl>: Mar 09 06:41PM +0100 W dniu 9.03.2023 o 18:35, Jivanmukta pisze: > Could it be hardware problem, not with my application? Probably not, because I can run my C++ program with different arguments. |
Jivanmukta <jivanmukta@poczta.onet.pl>: Mar 09 07:03PM +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. Question: how to TRACE values: identifiers[what].end(), ids.begin(), ids.end()? I failed to cast them to unsigned long. |
scott@slp53.sl.home (Scott Lurndal): Mar 09 06:05PM >undepending where I have set a breakpoint. >I also have SIGSEGV after TRACE when I run my application from command >prompt, not VSCode. Well, there's your problem. VScode is a POS. From the command line, prefix your application execution command with the string 'gdb -q --args '. When the sigsegv occurs, type 'bt' which will produce a stack traceback. 'info registers' will show the current register state at the time of the SIGSEGV 'x/i $pc' will show the machine instruction that caused the SIGSEGV. Look at the instruction to determine which register contains the address, then check the 'info registers' output to see what the address value is that caused the fault. |
scott@slp53.sl.home (Scott Lurndal): Mar 09 06:05PM >> 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? No. |
Jivanmukta <jivanmukta@poczta.onet.pl>: Mar 09 08:33PM +0100 W dniu 9.03.2023 o 19:05, Scott Lurndal pisze: > Look at the instruction to determine which register contains > the address, then check the 'info registers' output to see > what the address value is that caused the fault. (gdb) bt #0 0x000000000043d68e in __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx1998::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=0x7fffffffc1b0, __i=<error reading variable>) at /usr/include/c++/9/bits/stl_iterator.h:804 #1 0x000000000043a2aa in std::__cxx1998::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> > > >::end (this=0x50) at /usr/include/c++/9/bits/stl_vector.h:827 #2 0x0000000000436c09 in std::__debug::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> > > >::end (this=0x38) at /usr/include/c++/9/debug/vector:306 #3 0x00000000004488c3 in load_cache (cache_filename="dirtyphp_cache_frameworks.xml", parent_node_name=0x52f916 "frameworks", nodes_name=0x52f90c "framework", dir=L"/home/robert/Projekty/laravel-lodash/vendor/laravel", result_dir=L"/", options="", delim="~#@%_", cached=@0x7fffffffdd00: true, identifiers=0x0, strings=0x0) at src/cache.cpp:97 #4 0x000000000044982e in cache::load_framework_cache (this=0x7fffffffdd00, framework_dir=L"/home/robert/Projekty/laravel-lodash/vendor/laravel", delim="~#@%_", framework_identifiers=0x0) at src/cache.cpp:133 #5 0x000000000044a0c3 in cache::load_vendor_cache (this=0x7fffffffdd00, vendor_dir=L"/home/robert/Projekty/laravel-lodash/vendor", delim="~#@%_", dir_separator=L"/", framework_identifiers=std::__debug::unordered_map with 2 elements = {...}, third_party_identifiers=std::__debug::unordered_map with 48 elements = {...}) at src/cache.cpp:189 #6 0x000000000046c361 in obfuscator::get_cmdline_options (this=0x7fffffffd550, argc=8, argv=0x7fffffffdee8) at src/obfuscator.cpp:754 #7 0x00000000004240ba in main (argc=8, argv=0x7fffffffdee8) at src/dirtyphp.cpp:148 (gdb) info registers rax 0x58 88 rbx 0x38 56 rcx 0x7fffffffc390 140737488339856 rdx 0x58 88 rsi 0x58 88 rdi 0x7fffffffc1b0 140737488339376 rbp 0x7fffffffc190 0x7fffffffc190 rsp 0x7fffffffc190 0x7fffffffc190 r8 0x0 0 r9 0x7fffffffc0f0 140737488339184 r10 0x1 1 r11 0x246 582 r12 0x1 1 r13 0x0 0 r14 0x0 0 r15 0x0 0 rip 0x43d68e 0x43d68e <__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx1998::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(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >* const&)+20> eflags 0x10246 [ PF ZF IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb) x/i $pc => 0x43d68e <__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx1998::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(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >* const&)+20>: mov (%rax),%rdx |
scott@slp53.sl.home (Scott Lurndal): Mar 09 07:55PM > >::__normal_iterator(std::__cxx11::basic_string<char, >std::char_traits<char>, std::allocator<char> >* const&)+20>: mov >(%rax),%rdx So, RAX is the register that contains the address from which the data is being loaded. A virtual address less than 0x1000 is generally invalid on most operating systems in order to fault on NULL pointer dereferences. It likely means that your objects were not correctly initialized or have been overwritten inadvertantly by other code in your application. Next thing to try is to insert the following instead of 'gdb -q --args ' in front of your command on the command line. valgrind --leak-check=full --show-leak-kinds=all -v --log-file=/tmp/vg%p.log Then look at the generated log file to identify where things started to go wrong. |
Daniel <danielaparker@gmail.com>: Mar 09 11:38AM -0800 > catch(auto &[str,val]) > { > } Others have answered the question about your catch statement. I would also note that throwing a pair<string,int> isn't best practice, because a std:string can throw during copying. We don't want to throw in an exception copy constructor, lest we throw the wrong exception type. You may want to consider inheriting from std::runtime_error, and store the string part of your error message in it. std::runtime_error is guaranteed not to throw exceptions during copying, typically it stores the string internally as a separately-allocated reference-counted string. Daniel |
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:
Post a Comment