- Overload by return type - 6 Updates
- strcmp() ? ;-) - 6 Updates
- Hi every one .how can i write a program for differential equation with (x,t)variable?my equation exactly is:(∂(hc_i))/∂t+(∂(〖qc〗_i))/∂x =e_i+e_di+r_i 〖+r〗_ri-d_i, - 3 Updates
- Release of CC Mode 5.34 for (X)Emacs - 1 Update
- Namespace scopes and function implementation confusion - 1 Update
- CLOCKS_PER_SEC ? just curious - 3 Updates
- How to deal with running out of stack space? - 4 Updates
- Switching to C# - 1 Update
rick.c.hodgin@gmail.com: Jun 19 06:18AM -0700 Why doesn't C++ allow a function overload by the return type? Outwardly, it seems to be an arbitrary constraint. -- Rick C. Hodgin |
Bart <bc@freeuk.com>: Jun 19 02:27PM +0100 > Why doesn't C++ allow a function overload by the return type? > Outwardly, it seems to be an arbitrary constraint. Not familiar with function overloads in C++, but assuming you can have one f(int,int) that returns type T, and another f(int,int) that returns type U, which function is called here: cout << f(10,20); ? |
rick.c.hodgin@gmail.com: Jun 19 06:46AM -0700 On Wednesday, June 19, 2019 at 9:27:35 AM UTC-4, Bart wrote: > type U, which function is called here: > cout << f(10,20); > ? It wouldn't matter, because in that context any input value can be used, which means any return type T or U can be used. Either could be chosen and have it work. If you needed a specific one, then: cout << (U)f(10,20); In other cases, it would be contextual based on its use in the calling function. If it returned type T=int in one case, an type U=float in another: if (f(1, 2) == 3) // Assume int return type if (f(1, 2) == 3.0f) // Assume float return type In other cases it would be returning a class or struct. I can see it working in all cases except where there's ambiguity. struct SType1 { int x; int value; }; struct SType2 { int y; int value; }; // Return type overload SType1* f(void); SType2* f(void); // Use in code f()->x; // No ambiguity f()->y; // No ambiguity f()->value; // Ambiguity, generate a diagnostic ((SType1*)f())->value; // No ambiguity ((SType2*)f())->value; // No ambiguity -- Rick C. Hodgin |
Bart <bc@freeuk.com>: Jun 19 03:05PM +0100 >> ? > It wouldn't matter, because in that context any input value can > be used, which means any return type T or U can be used. If could matter because the two functions could do different things and you might specifically want one. (Or may not even be aware of the other.) Either > could be chosen and have it work. If you needed a specific one, > then: > cout << (U)f(10,20); That doesn't really fix it. Which function is called which is then cast to U? Use of a cast suggests the return type is something other than U, so either function could plausibly be called. > type U=float in another: > if (f(1, 2) == 3) // Assume int return type > if (f(1, 2) == 3.0f) // Assume float return type This doesn't follow. And actually you've hit on other problems: f(1,2) / f(3,4) Which version of f is used for each operand? The possible combinations are int/int, int/float, float/int, float/float, with different results. Now it can depend on how "/" is used! And that only differentiates between int/int (int result) and the rest (all float). Suppose there are also 2 g functions; one is g(int,int)->int, and the other is g(float,float)->float. Which g is called here: g(f(1,2),f(3,4)) ? > f()->value; // Ambiguity, generate a diagnostic > ((SType1*)f())->value; // No ambiguity > ((SType2*)f())->value; // No ambiguity Is this speculation for a feature in your new language? |
rick.c.hodgin@gmail.com: Jun 19 07:18AM -0700 On Wednesday, June 19, 2019 at 10:05:41 AM UTC-4, Bart wrote: > That doesn't really fix it. Which function is called which is then cast > to U? Use of a cast suggests the return type is something other than U, > so either function could plausibly be called. In the case of an overloaded return type, the cast would be used as a cue to determine which function to call. If there is one which returns that type, then use that one. If not, then look for suitable candidates and pick one generating a warning diag- nostic. If none are suitable, generate an error diagnostic. > > if (f(1, 2) == 3.0f) // Assume float return type > This doesn't follow. And actually you've hit on other problems: > f(1,2) / f(3,4) It is ambiguous and would generate a warning diagnostic. > Suppose there are also 2 g functions; one is g(int,int)->int, and the > other is g(float,float)->float. Which g is called here: > g(f(1,2),f(3,4)) ? It is ambiguous and would generate a warning diagnostic. > > ((SType1*)f())->value; // No ambiguity > > ((SType2*)f())->value; // No ambiguity > Is this speculation for a feature in your new language? No. I had need of this today. I wound up writing a marshaling function to handle the variable return types for me transparently to my use in code. This is how I come up with these ideas most of the time. I'm coding something, and in the midst of me coding I see how it could be done differently there in the moment. I consider it for a time and if it seems plausible I add it to my language, and if it's not so cut and dry I come here and ask questions. I think an overloaded type could be of benefit. I may be of greater use like this: String f(int, int); Integer f(int, int); Where the return types are so solidly different that it is then obvious which one to use in context. And where it is ambiguous, use a cast to indicate which one you want. It might even be a desirable thing to create a new auto-cast syntax for the over- loaded return type to something like this: String.f(1,2); // When you explicitly need the String f() Integer.f(1,2); // When you explicitly need the Integer f() I think I will add overloaded return types to CAlive, but it's not a priority. I already support multiple return values using a different function prototype syntax: function name | params int a, int b | returns char* c, float d, double e { // Reference the return values by name, as they // generally appear like local variables c = null; d = 0.0f; e = 0.0; // Or issue a hard return statement like this: return { null, 0.0f, 0.0 }; // If you're only filling partial slots with new // information, use the nocode keyword (used so // you indicate there is no code there, and that // it's on purpose, and not just something you // forgot): c = null; e = 0.0; return { nocode, 0.0f, nocode }; } -- Rick C. Hodgin |
jameskuyper@alumni.caltech.edu: Jun 19 07:53AM -0700 > Why doesn't C++ allow a function overload by the return type? > Outwardly, it seems to be an arbitrary constraint. Because the overload to be called is chosen based upon the types of the arguments passed to the function. If those types aren't different between two overloads, it can't determine which one to use. This is intimately related to a key principle that guided the design of C++, which was inherited from C: what an expression does when evaluated is determined entirely by the expression itself, not by the context it occurs in. How the result of that evaluation is handled does depend upon the context, but the evaluation itself does not. That statement does not quite say what I mean, and the simplest way I can come up with to correct it is to explain how it's wrong. The set of identifiers that are currently in scope is part of the context, and has a great deal of effect on how an expression is evaluated. However, if an expression is a sub-expression of another expression, the containing expression has no effect on how the sub-expression is evaluated. If an expression is a full-expression, it is necessarily part of some other piece of syntax, such as an if() statement. The fact that an if() statement's condition must be convertible to bool, for instance, does not influence how the expression is evaluated - it only determines whether or not the result of that evaluation is acceptable. This principle makes it easier to think about the meaning of C++ code, and I suspect it makes it easier to compile, too. I wouldn't hold up too much hope of convincing the C++ committee to make a decision that would violate this principle. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 18 08:01PM -0400 On 6/18/19 6:24 PM, Ben Bacarisse wrote: >> your proposed change. > Currently, strcmp(stringOne, stringTwo) returns 0 when the strings are > equal. The OP is proposing a change so that this would be 1. I responded too quickly, without reading carefully enough. I assumed his proposal was more sane than it actually was. I should have said that "if(!strcmp(stringOne,stringTwo)) does the same thing under the G G's proposal that if(strcmp(stringOne,stringTwo))", with corresponding changes to the other comments I made. Furthermore, I should have been more emphatic about the impossibility of getting this changed - this will not merely break a lot of existing code that uses strcmp() - it will break all existing code that uses it. |
Keith Thompson <kst-u@mib.org>: Jun 18 06:03PM -0700 > given strings : stringOne, stringTwo are equal > that strcmp( stringOne, stringTwo ) will return true with a value of 1 or > bool = true No, because it would break existing code. The result of strcmp() is not a boolean (yes/no, true/false) value. It's a *number*, with different meanings for negative, zero, and positive values. I do see the advantages of having boolean string comparison functions that work like the <, <=, ==, !=, >, and >= operators on scalars. And I personally dislike code that treats strcmp()'s result as if it were boolean, such as: if (!strcmp(s1, s2) /* s1 and s2 equal */ If you really want boolean comparisons for strings you can roll your own: #define STR_EQ(s1, s2) (strcmp((s1), (s2)) == 0) #define STR_NE(s1, s2) (strcmp((s1), (s2)) != 0) #define STR_LT(s1, s2) (strcmp((s1), (s2)) < 0) #define STR_LE(s1, s2) (strcmp((s1), (s2)) <= 0) #define STR_GT(s1, s2) (strcmp((s1), (s2)) > 0) #define STR_GE(s1, s2) (strcmp((s1), (s2)) >= 0) But with more experience working with C, I think you'll find that these macros just aren't necessary. Any C programmer who has worked with strings knows how strcmp() works, and can read `strcmp(s1, s2) < 0` as easily as `STR_LT(s1, s2)`. In fact, the strcmp() version is probably easier to read, because it doesn't require finding and understanding the macro definition. If a future version of the language added standard streq(), strne(), et al as functions (possibly implemented as macros) to <string.h>, I wouldn't object, but I doubt that's going to happen. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 19 06:02AM +0200 On 18.06.2019 23:36, G G wrote: > and maybe a new function strcmpOrder( string string1, string string2 ) > where if string1 comes before string2 returns a 1 > if not return 0; The functions you mention are for comparing C strings, zero-terminated strings represented by pointers. Up at the C++ level `strcmp` corresponds to `std::string::compare`. But `std::string` also offers the usual relational operators, like `==`, `>` and so on, and the easiest way to get that notation for strings is to just use `std::string`. > lol > there is probably something better to come 14 more chapters to go. > :-) Hm, which book? Anyway, the `strcmp`, `memcmp`, `std::string::compare` family of functions, or at least the concept they embody, are about to have a renaissance with the introduction of the spaceship operator in C++20. The concept is roughly this: since the non-zero result values are not specified one can use *any* values, and for example lexicographically compare two struct instances this way: struct S{ int x; int y; int z; }; auto compare( const S& a, const S& b ) -> int { if( const int r = a.x - b.x ) { return r; } if( const int r = a.y - b.y ) { return r; } if( const int r = a.z - b.z ) { return r; } // Redundant, but. return 0; } Then the relational operators can easily and efficiently be expressed in terms of, and automatically generated from, the single compare function. A manual definition of one of them: auto operator<( const S& a, const S& b ) -> bool { return compare( a, b ) < 0; } If you try to express this function directly, without a function like compare doing the brunt work, then you get into complexity where it's very easy to step wrong, and then e.g. standard collections don't work. That problem is reduced, though, when one learns about the `std::tuple` based workaround, auto operator<( const S&a, const S&b ) -> bool { using std::tie; return tie( a.x, a.y, a.z ) < tie( b.x, b.y, b.z ); } Here the `std::tuple::operator<` does the work, guaranteed correctly, although possibly not as efficiently as compare. But on the third hand with modern computers efficiency is no longer a matter of counting basic operations. So it might be just as efficient, or even more. It's just very much more work to do, with much redundancy, in general. Cheers & hth., - Alf |
queequeg@trust.no1 (Queequeg): Jun 19 10:26AM > I doubt it. You might have to make your own functions, eg: True. > int streq(char* s, char* t) { return strcmp(s,t)==0;} > int strlt(char* s, char* t) { return strcmp(s,t)<0;} But please, please, please, use const in such situations. I've seen too many functions that obviously don't modify the string, but don't care about const, and it breaks the program logic. Consider: static void function(const char *argument) { static const char * const test = "test"; if (streq(argument, test)) { // ... } } -- https://www.youtube.com/watch?v=9lSzL1DqQn0 |
Juha Nieminen <nospam@thanks.invalid>: Jun 19 10:34AM > given strings : stringOne, stringTwo are equal > that strcmp( stringOne, stringTwo ) will return true with a value of 1 or > bool = true No. On the contrary, the upcoming operator<=> will rely on the implementation using exactly that kind of results for comparisons. There's a reason for that. |
Manfred <noname@add.invalid>: Jun 19 02:01PM +0200 On 6/18/2019 11:36 PM, G G wrote: > lol > there is probably something better to come 14 more chapters to go. > :-) As others have said, there's no chance for such a change. In addition to being a breaking change for zillions of lines of existing code, strcmp yields more than an equality test, it also delivers total ordering on strings, which is a widely required feature. And the implementation of strcmp yields ordering with zero extra cost compared to a pure equality test. |
shahla yavari <shahlayavari3@gmail.com>: Jun 18 08:13PM -0700 (∂(hc_i))/∂t+(∂(〖qc〗_i))/∂x =e_i+e_di+r_i 〖+r〗_ri-d_i, |
Real Troll <real.troll@trolls.com>: Jun 19 12:35AM -0400 On 19/06/2019 04:13, shahla yavari wrote: > (∂(hc_i))/∂t+(∂(〖qc〗_i))/∂x =e_i+e_di+r_i 〖+r〗_ri-d_i, Please start here first: <https://www.codeproject.com/Articles/43607/Solving-ordinary-differential-equations-in-C> You need to learn how to use Google Search Engine as it has most answers to get started. Good luck. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 19 07:53AM -0400 On 6/18/19 11:13 PM, shahla yavari wrote: > (∂(hc_i))/∂t+(∂(〖qc〗_i))/∂x =e_i+e_di+r_i 〖+r〗_ri-d_i, You need a symbolic math package to handle such equations in that form. The two I'm most familiar with are called Mathematica and Maple. I haven't used such packages in a long time, so it's entirely possible that there's more modern symbolic math systems that are much better than those. While you can't handle such equations in that form in C++, it's possible to write C++ code to solve partial differential equations numerically. A key concept in putting together such solutions is to approximate the partial derivatives with finite-differences: the partial derivative of f(x,y) with respect to x at the point x0,y0 can be approximated by (f(x0+deltax,y0) - f(x0,y0))/deltax, where deltax is the spacing of your discrete approximation to f in the x direction. However, you don't have a well-posed problem until you've specified boundary conditions for the solution - the fact that you didn't mention any suggests that you're not quite ready to do something like that. There's lots and lots of subtleties that need to be dealt with. For instance, it's quite easy to misuse finite-difference approximations to justify an algorithm for solving the equations that, instead of converging on a valid solution, diverges exponentially away from a valid solution. You need to take some courses and/or read some advanced books on numerical methods before even attempting to do such things. |
Alan Mackenzie <acm@muc.de>: Jun 19 11:11AM Release Announcement CC Mode Version 5.34 Alan Mackenzie This message announces the availability of a new version of CC Mode, an Emacs and XEmacs mode for editing C (ANSI and K&R), C++, Objective-C, Java, CORBA's IDL, Pike and AWK code. A list of user visible changes is detailed in the NEWS file and in the URL listed below. More information, including links to download the source, are available on the CC Mode web page: <http://cc-mode.sourceforge.net/> Send email correspondence to bug-cc-mode@gnu.org For a list of changes please see <http://cc-mode.sourceforge.net/changes-534.php> -- Alan Mackenzie (Nuremberg, Germany). |
Juha Nieminen <nospam@thanks.invalid>: Jun 19 10:40AM If I had been asked if this compiles, I would have answered "no". At least clang disagrees with me. I assume it's right. And I'm both wrong and very confused. //--------------------------------------------------------- #include <iostream> namespace ANamespace { struct Data { int mValue; bool operator<(const Data&) const; }; } class AClass { public: using Inner = ANamespace::Data; }; // This compiles??? bool AClass::Inner::operator<(const Data& rhs) const { return mValue < rhs.mValue; } int main() { AClass::Inner d1 { 5 }, d2 { 10 }; std::cout << (d1 < d2) << "\n"; ANamespace::Data d3 { 20 }, d4 { 15 }; std::cout << (d3 < d4) << "\n"; } //--------------------------------------------------------- |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 18 08:05PM -0400 On 6/18/19 7:20 PM, G G wrote: > depending on the cpu, clock cycles... is it somehow > assigned or read and calculated from the bios or uefi. > ctime / time.h header files CLOCKS_PER_SEC is a macro "which expands to an expression with type clock_t" (7.27.1p2). That description allows for the possibility that it expands into a function call, which might do any of the things you're talking about. |
Keith Thompson <kst-u@mib.org>: Jun 18 07:01PM -0700 > depending on the cpu, clock cycles... is it somehow > assigned or read and calculated from the bios or uefi. > ctime / time.h header files The CLOCKS_PER_SEC macro yields the precision of the value returned by the clock() function. It doesn't *necessarily* correspond to any physical characteristic of the system. An imaginary example: if CLOCKS_PER_SEC is one million (as it is on POSIX systems), the value returned by clock() represents a number of microseconds, but it might always be a multiple of 1000, indicating an underlying resolution of 1 millisecond. As James Kuyper points out, the standard's definition of CLOCKS_PER_SEC allows it to vary (though presumably it would keep the same value for a run of a program), but on many (most?) systems it's defined as a constant. In fact, I'd be at least mildly surprised if there were a system with CLOCKS_PER_SEC not defined as a constant. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
Juha Nieminen <nospam@thanks.invalid>: Jun 19 10:37AM > compilers and cpu and clock cycles can be different > depending on the cpu, clock cycles... is it somehow > assigned or read and calculated from the bios or uefi. Even if CLOCKS_PER_SEC is, for example, 1000, that doesn't mean you are going to get the timing at 1ms of accuracy. The values may well jump by more than 1. That value only indicates what you need to divide std::clock() by in order to get seconds. It doesn't indicate what the accuracy of that function is. (It may well be more or less accurate than that.) Internally, whatever the system uses will get scaled so that the multiplier will be CLOCKS_PER_SEC. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 18 07:57PM -0400 On 6/18/19 8:49 AM, Paavo Helde wrote: ... > For emulating a stack std::deque would be a better option than std::vector. Why? Actually, I'd think that std::stack<T, std::vector<T> > would be slightly better for emulating a stack: it would allow you to use push() and pop(). |
Melzzzzz <Melzzzzz@zzzzz.com>: Jun 19 04:29AM > Actually, I'd think that > std::stack<T, std::vector<T> > would be slightly better for emulating a > stack: it would allow you to use push() and pop(). There is no point. Local variables and constants cannot be placed in that vector. We will always depend on stack size being limited. Compiler can always use segmented stacks, but alas for performance reasons they don't want to do that.... -- press any key to continue or any other to quit... U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi bili naoruzani. -- Mladen Gogala |
Paavo Helde <myfirstname@osa.pri.ee>: Jun 19 08:38AM +0300 On 19.06.2019 2:57, James Kuyper wrote: > ... >> For emulating a stack std::deque would be a better option than std::vector. > Why? The same reasons why std::stack defaults to using std::deque underneath. With a stack you typically only work with a small part of it, std::deque ensures that small parts are compact in memory, and at the same time it does not waste time on reallocating and copying over all elements when it needs to grow. OTOH, std::deque has a bit more indirection when accessing the elements, which might or might not be significant. Anyway, the choice depends on the usage case and should be measured/profiled. > Actually, I'd think that > std::stack<T, std::vector<T> > would be slightly better for emulating a > stack: it would allow you to use push() and pop(). I have often tried to use std::stack, then discovered I still need to access elements beneath top(), and switched over to plain std::deque or std::vector. |
David Brown <david.brown@hesbynett.no>: Jun 19 11:18AM +0200 On 19/06/2019 06:29, Melzzzzz wrote: > that vector. We will always depend on stack size being limited. > Compiler can always use segmented stacks, but alas for performance > reasons they don't want to do that.... Compilers /do/ use segmented stacks - with the right compiler, options, target cpu, host OS, etc. Look up gcc's "split stack" feature for example - and no doubt other compilers have support too. It is not a feature you'd want without reason, as it complicates (and thus slows down) the code - but in some cases it is worth using. |
Melzzzzz <Melzzzzz@zzzzz.com>: Jun 19 04:26AM >>> Not dead yet. Knocking on wood... :^) >> You are not on Ultimate Good side already? > I always try to be a nice person: Is that good enough? Seems so ;) -- press any key to continue or any other to quit... U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi bili naoruzani. -- Mladen Gogala |
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