- Does the call from P() to H() specify infinite recursion? - 6 Updates
- Understanding invalid user input - 17 Updates
- More of my philosophy about C++ and Rust and Microsoft and safety-critical systems.. - 1 Update
- More of my philosophy about memory safety and inheritance in programming languages.. - 1 Update
| olcott <NoOne@NoWhere.com>: Nov 11 10:00AM -0600 #define ptr uintptr_t void P(ptr x) { H(x, x); } int H(ptr x, ptr y) { ((void(*)(ptr))x)(y); return 1; } int main() { H((ptr)P, (ptr)P); return 0; } -- Copyright 2021 Pete Olcott "Great spirits have always encountered violent opposition from mediocre minds." Einstein |
| Marcel Mueller <news.5.maazl@spamgourmet.org>: Nov 11 07:01PM +0100 Am 11.11.21 um 17:00 schrieb olcott: > H((ptr)P, (ptr)P); > return 0; > } Besides the fact that there is no good reason to write that type unsafe code in C++ did you test it? The code will never compile because of the forward reference to H. And well, H calls P and P calls H. What do you expect? Marcel |
| olcott <NoOne@NoWhere.com>: Nov 11 12:52PM -0600 On 11/11/2021 12:01 PM, Marcel Mueller wrote: > forward reference to H. > And well, H calls P and P calls H. What do you expect? > Marcel Yes the code does compile and I did test it. This is the pure C part of my halting theorem refutation. I wanted to get some C experts to weigh in on the the analysis of the C code. I won't be discussing anything besides the pure C aspects here because people here get upset. -- Copyright 2021 Pete Olcott "Great spirits have always encountered violent opposition from mediocre minds." Einstein |
| Jeff Barnett <jbb@notatt.com>: Nov 11 12:06PM -0700 On 11/11/2021 11:01 AM, Marcel Mueller wrote: > code in C++ did you test it? The code will never compile because of the > forward reference to H. > And well, H calls P and P calls H. What do you expect? I expect that PO (the OP) is nuts and lonesome. This crap is just another bid for attention and companionship, no matter the quality of the interaction. However many programing languages allow 'mutual recursion" and it's very useful. Common LISP, for example, has two different forms for lexically binding functions. One makes the bound functions only visible within the body of the binding form; the other makes these functions visible in the bodies of the bound functions themselves as well as the body of the binding form. Further, the batch compilers do not output "missing function definition" warnings or errors until the entire batch has been compiled. Together these features allow incremental development and debugging as well as mutual recursion. And as an aside, I think that Common LISP has at least as flexible and powerful an object system as does any of the C variants. -- Jeff Barnett |
| Richard Damon <Richard@Damon-Family.org>: Nov 11 02:20PM -0500 On 11/11/21 1:52 PM, olcott wrote: > get some C experts to weigh in on the the analysis of the C code. > I won't be discussing anything besides the pure C aspects here because > people here get upset. First, this CAN'T be the complete definition of the source file, as at minimum it needs a #include <stdint.h> to get the definition of uintptr_t Second, if you are using a version of C that has uintptr_t defined, (C99 or later) then the lack of a declaration for H in P is an error Only C90 and before allowed the calling of a function with no declaration before it. It might 'compile', but if it does, it will include a manditory diagnostic, and that means that if the compiler still produced an output file, if you run that program, the behavior of that program is BY DEFINITON of the Standard, Undefined. Thus, there ARE NO 'C aspects' of this 'program' as the C standard has declared that it suppies NO definition of what it does. FAIL. |
| olcott <NoOne@NoWhere.com>: Nov 11 01:26PM -0600 On 11/11/2021 1:06 PM, Jeff Barnett wrote: > I expect that PO (the OP) is nuts and lonesome. This crap is just > another bid for attention and companionship, no matter the quality of > the interaction. (Attacking the person): This fallacy occurs when, instead of addressing someone's argument or position, you irrelevantly attack the person or some aspect of the person who is making the argument. https://www.txstate.edu/philosophy/resources/fallacy-definitions/Ad-Hominem.html > debugging as well as mutual recursion. > And as an aside, I think that Common LISP has at least as flexible and > powerful an object system as does any of the C variants. That is the strawman error. I am only referring to the x86 machine code specified by this Microsoft C source-code. #define ptr uintptr_t void P(ptr x) { H(x, x); } int H(ptr x, ptr y) { ((void(*)(ptr))x)(y); return 1; } int main() { H((ptr)P, (ptr)P); return 0; } -- Copyright 2021 Pete Olcott "Great spirits have always encountered violent opposition from mediocre minds." Einstein |
| Bonita Montero <Bonita.Montero@gmail.com>: Nov 11 07:33AM +0100 >> } > Or alternatively dump most of that over complicated crap and just use strtof() > C++ reinventing the wheel once aqain. Does it parse non-parseable values into a NaN ? |
| Bonita Montero <Bonita.Montero@gmail.com>: Nov 11 07:36AM +0100 Am 10.11.2021 um 17:20 schrieb Alf P. Steinbach: > `>>` formatted input. > Conversely, when you use `>>` you can let `>>` parse the input. > I see no advantage in both using `>>` and parsing the input. How get parsing-errors signalled when using getline or operator >> ? |
| Juha Nieminen <nospam@thanks.invalid>: Nov 11 06:54AM > using namespace std; Out of curiosity, where did you learn to write that? |
| Joseph Hesse <joeh@gmail.com>: Nov 11 10:55AM +0200 On 11/11/21 08:54, Juha Nieminen wrote: > Joseph Hesse <joeh@gmail.com> wrote: >> using namespace std; > Out of curiosity, where did you learn to write that? I don't remember where I first learned it. I've been writing C++ programs on and off for the last 20 years. In order to avoid writing lots of "std::cout" kind of statements I use it. I wouldn't use it in production code. The code I presented was just to test something. Out of curiosity, why do you ask? |
| DozingDog@thekennel.co: Nov 11 09:58AM On Thu, 11 Nov 2021 07:33:09 +0100 >strtof() >> C++ reinventing the wheel once aqain. >Does it parse non-parseable values into a NaN ? Why not read the man page. You check the pointer return values instead, no isnan() required. |
| Juha Nieminen <nospam@thanks.invalid>: Nov 11 11:42AM > lots of "std::cout" kind of statements I use it. I wouldn't use it in > production code. The code I presented was just to test something. > Out of curiosity, why do you ask? Because I'm fascinated by what I find to be a rather odd psychological aversion that many people have towards the "std::" prefix, usually for no logical nor rational reason. (And no, I'm not asking for your rationale or reasons. I have heard it all a million times. Nothing is even close to convincing, sorry. I'm just explaining what I find interesting about this.) I'm also curious about how "using namespace std;" became so ubiquitous. Why did its use spread like a wildfire, and persists to this day? Where do people learn it? Why do people use it? Is it cargo cult programming? Do people just see it being used in tutorials and examples, and start repeating it with no second thought about it? Why does there seem to be such a strong instinct to write that line in order to get rid of the "std::" prefix? You see it all the time, and it just puzzles me where this tidbit of habit comes from and how people learn it. Perhaps the psychology behind it is closely related to the psychology behind so many programmers using variable and function names that are needlessly short to the point of being detrimental to the readability and understandability of the code. (I think one quintessential example of this is POSIX: If you look at all the names, function names, macro names, variable names... defined by POSIX, you'll notice a clear pattern of brevity over clarity in many cases. Sure, POSIX itself is not really to blame here, because it simply officially standardized what was an bunch of unofficial "standards", and it just took most of the existing stuff as-is, without wanting to change it, for backwards compatibility. However, regardless of who is responsible for those names, it just quite clearly shows the brevity-over-clarity psychology behind it.) |
| Bonita Montero <Bonita.Montero@gmail.com>: Nov 11 01:03PM +0100 >> Does it parse non-parseable values into a NaN ? > Why not read the man page. You check the pointer return values instead, no > isnan() required. I don't see any big difference when using strtof. It would result in almost the same code. |
| Bonita Montero <Bonita.Montero@gmail.com>: Nov 11 01:06PM +0100 Am 11.11.2021 um 12:42 schrieb Juha Nieminen: > Because I'm fascinated by what I find to be a rather odd psychological > aversion that many people have towards the "std::" prefix, usually for > no logical nor rational reason. Writing using namespace std is ok ! People know std::'s symbols and no library writer has his own symbols that collide with std::. > I'm also curious about how "using namespace std;" became so ubiquitous. You're compulsive and intolerant. It's just a matter of taste. |
| Juha Nieminen <nospam@thanks.invalid>: Nov 11 01:11PM > I don't see any big difference when using strtof. > It would result in almost the same code. Actually what strtof() accepts as input depends on the current locale, while the input format of from_chars() is fixed and does not depend on the locale. This can seriously bite you in the posterior when you assume that, for example, the decimal point of the ascii representation of the number will be a '.'. The locale might change strtof() to assume it's ',' instead, and you'll get weird results (where the decimal part isn't parsed, and ends the parsing at the dot.) |
| Juha Nieminen <nospam@thanks.invalid>: Nov 11 01:16PM >> no logical nor rational reason. > Writing using namespace std is ok ! People know std::'s symbols > and no library writer has his own symbols that collide with std::. Using the std:: prefix make the code easier to understand. For example, suppose you see this line of code: if(equal(a, b, c)) do you know what function is that calling? If you don't happen to remember if there's a standard library function with that name, you'll probably think that it's some custom function, and you'll have no idea what kind of parameters it's taking (and why it's taking three of them). Contrast that with: if(std::equal(a, b, c)) Now there's no doubt and no ambiguity. You know *exactly* where that function is (in the standard library), even if you didn't know that such a function exists in the standard library. If you do know the function, then you'll also know that 'a', 'b' and 'c' there are some kind of iterators, and you know what the function is doing. (Without that knowledge you would have no idea what 'a', 'b' and 'c' are.) All that just thanks to a little "std::" there. > You're compulsive and intolerant. It's just a matter of taste. Look who's talking. |
| Bonita Montero <Bonita.Montero@gmail.com>: Nov 11 02:27PM +0100 Am 11.11.2021 um 14:16 schrieb Juha Nieminen: >> Writing using namespace std is ok ! People know std::'s symbols >> and no library writer has his own symbols that collide with std::. > Using the std:: prefix make the code easier to understand. That's a matter of taste. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Nov 11 08:32AM -0500 On 11/11/21 8:11 AM, Juha Nieminen wrote: ... > number will be a '.'. The locale might change strtof() to assume > it's ',' instead, and you'll get weird results (where the > decimal part isn't parsed, and ends the parsing at the dot.) Or, you can get precisely the results you desire, if you're reading digit strings in the format that's appropriate to the current locale. The solution, as always, it to make sure that the current locale is the correct one for what you're currently trying to do. |
| Paavo Helde <myfirstname@osa.pri.ee>: Nov 11 04:13PM +0200 11.11.2021 15:32 James Kuyper kirjutas: > digit strings in the format that's appropriate to the current locale. > The solution, as always, it to make sure that the current locale is the > correct one for what you're currently trying to do. This is not possible in general. The locale is process global, so it will fail if I want to work with some human-readable data in current user locale in one thread, and with some machine-readable fixed data format in another thread. Calling setlocale() in a multithreaded program after startup is extremely problematic and will cause UB if another thread is executing any locale-dependent function at the same time. An option would be to use a stream with imbued locale, but this won't work for things discussed here, like strtof(). In practice one should use functions like strtof() for locale-specific things, and functions like from_chars() for fixed data formats. As an extra bonus, the latter often work significantly faster. |
| "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu>: Nov 11 07:58AM -0800 On Thursday, November 11, 2021 at 1:33:27 AM UTC-5, Bonita Montero wrote: > Am 10.11.2021 um 18:12 schrieb Dozi...@thekennel.co: ... > > Or alternatively dump most of that over complicated crap and just use strtof() > > C++ reinventing the wheel once aqain. The C++ standard defines std::stof() as calling std::strtof() when passed a narrow string, and it defines std::num_get<>::do_get() as calling std::strtof() if the final argument is a float. Therefore, C++ is not reinventing the wheel, it's re-using the wheel invented by C. > Does it parse non-parseable values into a NaN ? That doesn't make sense - if it's non-parseable, how could it be parsed? There's several different things that could prevent a string from being parsed. All of them are reported back to the caller, one way or another. However, in none of those cases is the value returned a NaN. A NaN is only returned when the correct parse of that string indicates that the returned value should be a NaN. C++ doesn't explain this directly, cross-referencing the C standard for it's description of strtof(): "If the subject sequence is empty or does not have the expected form, no conversion is performed; the value of nptr is stored in the object pointed to by endptr , provided that endptr is not a null pointer." (7.22.1.5p7). "If no conversion could be performed, zero is returned. If the correct value overflows and default rounding is in effect (7.12.1), plus or minus ... HUGE_VALF ... is returned (according to the ... sign of the value), and the value of the macro ERANGE is stored in errno . If the result underflows (7.12.1), the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether errno acquires the value ERANGE is implementation-defined." (7.22.1.5p10). |
| Bonita Montero <Bonita.Montero@gmail.com>: Nov 11 05:06PM +0100 > wheel invented by C. >> Does it parse non-parseable values into a NaN ? > That doesn't make sense - if it's non-parseable, how could it be parsed? NaN might be a proper representation for invalid values depending on what you're parsing. Rest of your nonsense unread. |
| "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu>: Nov 11 10:08AM -0800 On Thursday, November 11, 2021 at 11:06:54 AM UTC-5, Bonita Montero wrote: > Am 11.11.2021 um 16:58 schrieb james...@alumni.caltech.edu: > > On Thursday, November 11, 2021 at 1:33:27 AM UTC-5, Bonita Montero wrote: ... > > That doesn't make sense - if it's non-parseable, how could it be parsed? > NaN might be a proper representation for invalid values depending on > what you're parsing. If it's not parseable, a parsing function other than strtof() might produce a NaN anyway - but by definition it could not do so by parsing it, but only by recognizing it as unparseable. However, as specified in the text I cited from the standard, that's not what strtof() does with unparseable input - it's required to return 0. strtof() can produce a NaN, but to make that happen you have to pass it a parseable string starting with an optional + or - sign, and followed by either NAN or NAN(n-char-sequence). The n-char-sequence can carry an arbitrary mix of digits and nondigits. Contrary from what you might conclude from the name. a nondigit is not defined as "anything that isn't a digit". Rather, nondigits are defined by 6.2.4.1p2 as including only ' _', a-z or A-Z. The n-char-sequence is used, in an implementation-defined way, to determine the corresponding NaN payload, which can be retrieved using getpayload(). > Rest of your nonsense unread. It's not nonsense - or at least, if it is nonsense, it's not mine. Most of that message was simply a direct quote from the relevant standard. If you had bothered to read it, it would have answered your question. |
| Bonita Montero <Bonita.Montero@gmail.com>: Nov 11 07:27PM +0100 > Contrary from what you might conclude from the name. a nondigit is not defined as > "anything that isn't a digit". Rather, nondigits are defined by 6.2.4.1p2 as including only > ' _', a-z or A-Z. strof() wouln't make a big difference. |
| Amine Moulay Ramdane <aminer68@gmail.com>: Nov 11 09:10AM -0800 Hello, More of my philosophy about C++ and Rust and Microsoft and safety-critical systems.. I am a white arab from Morocco, and i think i am smart since i have also invented many scalable algorithms and algorithms.. I invite you to read the following from Microsoft about Rust programming language: Microsoft: Rust Is the Industry's 'Best Chance' at Safe Systems Programming https://thenewstack.io/microsoft-rust-is-the-industrys-best-chance-at-safe-systems-programming/ I think that the above article is not correct, since i think that Rust is suited for safety-critical systems, so i think Rust is better than C++ in the safety-critical systems, but i think that C++ will still be useful with the Address sanitization and ThreadSanatizer, and read my below thoughts since i have just added something in them: More of my philosophy about memory safety and inheritance in programming languages.. "Address sanitization is not a security feature, nor does it provide memory-safety: it's a debugging tool. Programmers already have tools to detect that the code they've written has memory problems, such as use-after-free or memory leaks. Valgrind is probably the best-known example. This gcc feature provides (some of) the same functionality: the only new thing is that it's integrated with the compiler, so it's easier to use. You wouldn't have this feature turned on in production: it's for debugging only. You compile your tests with this flag, and automatically they detect memory errors that are triggered by the test. If your tests aren't sufficient to trigger the problem, then you still have the problem, and it'll still cause the same security flaws in production. Rust's ownership model prevents these defects by making programs that contain such defects invalid: the compiler will not compile them. You don't have to worry about your tests not triggering the problem, because if the code compiles, there cannot be a problem. The two features are for different sets of problems. One feature of address sanitization is to detect memory leaks (allocating memory and neglecting to free it later). Rust makes it harder to write memory leaks than in C or C++, but it's still possible (if you have circular references). Rust's ownership model prevents data races in sequential and multi-threaded situations (see below). Address sanitization doesn't aim to detect either of those cases. But you can use ThreadSanatizer" And using just plain C#, it has better memory protection, since the GC and runtime make it impossible to leak, double-free, or access out-of-bounds. C# has unsafe blocks just like Rust does. Safe Rust is just as safe from memory safety problems as safe C#. I think that a programming language has to provide "inheritance", and the new Rust programming language doesn't provide it and i think that it is a deficiency in Rust, here is why: As a software developer you have to become more efficient and productive. So you need to make sure the code you write is easily reusable and maintainable. And, among other things, this is what inheritance gives you - the ability to reuse without reinventing the wheel, as well as the ability to easily maintain your base object without having to perform maintenance on all similar objects. Thank you, Amine Moulay Ramdane. |
| Amine Moulay Ramdane <aminer68@gmail.com>: Nov 11 08:53AM -0800 Hello, More of my philosophy about memory safety and inheritance in programming languages.. I am a white arab from Morocco, and i think i am smart since i have also invented many scalable algorithms and algorithms.. "Address sanitization is not a security feature, nor does it provide memory-safety: it's a debugging tool. Programmers already have tools to detect that the code they've written has memory problems, such as use-after-free or memory leaks. Valgrind is probably the best-known example. This gcc feature provides (some of) the same functionality: the only new thing is that it's integrated with the compiler, so it's easier to use. You wouldn't have this feature turned on in production: it's for debugging only. You compile your tests with this flag, and automatically they detect memory errors that are triggered by the test. If your tests aren't sufficient to trigger the problem, then you still have the problem, and it'll still cause the same security flaws in production. Rust's ownership model prevents these defects by making programs that contain such defects invalid: the compiler will not compile them. You don't have to worry about your tests not triggering the problem, because if the code compiles, there cannot be a problem. The two features are for different sets of problems. One feature of address sanitization is to detect memory leaks (allocating memory and neglecting to free it later). Rust makes it harder to write memory leaks than in C or C++, but it's still possible (if you have circular references). Rust's ownership model prevents data races in sequential and multi-threaded situations (see below). Address sanitization doesn't aim to detect either of those cases." And using just plain C#, it has better memory protection, since the GC and runtime make it impossible to leak, double-free, or access out-of-bounds. C# has unsafe blocks just like Rust does. Safe Rust is just as safe from memory safety problems as safe C#. I think that a programming language has to provide "inheritance", and the new Rust programming language doesn't provide it and i think that it is a deficiency in Rust, here is why: As a software developer you have to become more efficient and productive. So you need to make sure the code you write is easily reusable and maintainable. And, among other things, this is what inheritance gives you - the ability to reuse without reinventing the wheel, as well as the ability to easily maintain your base object without having to perform maintenance on all similar objects. Thank you, Amine Moulay Ramdane. |
| 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