- Let's talk about multiple inheritance and interfaces. - 3 Updates
- Name for a kind of function - 1 Update
- TDD considered harmful - 4 Updates
- Unit testing (Re: Putting project code in many different files) - 13 Updates
- Name for a kind of function - 1 Update
- 'int' considered dangerous (reprise) - 1 Update
- Iterator fun - 2 Updates
Juha Nieminen <nospam@thanks.invalid>: Feb 01 09:30AM > Premise: Multiple inheritance is universally accepted as bad When asked *why* multiple inheritance is bad, one, and only one example is always and ever given: Diamond inheritance. So why not say that diamond inheritance is bad, rather than multiple inheritance? Why is MI blamed for a different pattern? There is absolutely nothing wrong with multiple inheritance. Not from a practice point of view nor from a design point of view. From a design point of view inheritance creates an "is-a" relationship. Multiple inheritance simply adds additional "is-a" relationships (which I like to call "and-a"). For example: class Button: public Widget, public ReferenceCountable means "Button is-a Widget and-a ReferenceCountable (object)" The above example also demonstrates why multiple inheritance is useful. Ostensibly both Widget and ReferenceCountable have members and methods of their own, and their usage in this situation is sensible. "Interfaces" are nothing more than a crippled form of multiple inheritance. Saying otherwise is silly. The design relationship is exactly the same (your class will have an "is-a" relationship with an interface in the exact same way as with an actual class. There is no practical difference.) The crippling of interfaces simply causes needless code repetition in many cases (because the same methods need to be implemented again and again; moreover, many of the languages offering interfaces do not offer any way of avoiding this code repetition.) Code repetition is one of the worst designs in programming. Why not allow method implementations and members in interfaces? There is no technical nor designwise reason not to allow that. Simply disallow diamond inheritance if that's so scary. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
scott@slp53.sl.home (Scott Lurndal): Feb 01 02:02PM >>show how virtual inheritance works. > We do care about proper lifetime control in this newsgroup and > usually use smart pointers instead of raw pointers, even if it Speak for yourself, kemosabe. |
"Öö Tiib" <ootiib@hot.ee>: Feb 01 06:26AM -0800 On Monday, 1 February 2016 16:02:26 UTC+2, Scott Lurndal wrote: > > We do care about proper lifetime control in this newsgroup and > > usually use smart pointers instead of raw pointers, even if it > Speak for yourself, kemosabe. Was "kemosabe" mean here as "trusty scout" or "faithful friend"? |
Victor Bazarov <v.bazarov@comcast.invalid>: Feb 01 09:22AM -0500 On 2/1/2016 6:22 AM, Stefan Ram wrote: > When a function »m« calls another function »f«, we call »m« a > »client« of »f«, but how to we call »f« then? One does not > call a function a »server«, does one? In the latter case I'm more familiar with referring to 'm' as a "caller" (usually inside the 'f' function), and if one has to give 'f' a special name, it's a "called function". However, given that the compiler is free to inline the code (or refrain from generating the code that would call it _at all_ in some cases), no special term is in common use, I believe. I have heard a "callee", but not often enough to make it customary. V -- I do not respond to top-posted replies, please don't ask |
Robert Wessel <robertwessel2@yahoo.com>: Feb 01 01:01AM -0600 On Mon, 01 Feb 2016 01:17:06 +0200, Paavo Helde >Private methods are untestable only if they are never called by the >public methods. TDD tests the features and does not care how the class >provides these features. While TDD is not our prime methodology, we commonly* have** "friend class TestAbc;" in our definitions of class Abc (a bit of additional fiddle - namely a forward declaration of class TestAbc - needed if there's a namespace involved). At least for those cases when we want tests for private functions. Ugly? A bit, sure. And yes, it requires the maintenance of enough discipline so that people don't write TestAbc classes just to poke around where they oughtn't. *FSVO "commonly" **For historical reasons the prefix string is actually "tharness" rather than "Test". |
leigh.v.johnston@googlemail.com: Feb 01 04:23AM -0800 Designing software through trial and error by fixing failing "tests" rather than by applying some intelligence and thinking about abstractions, interfaces, class hierarchies and object hierarchies is, quite frankly, both absurd and possibly even harmful and I am amazed that you cannot see this. TDD is the totally wrong approach to software development. Design first, implement second and unit test third. |
"Öö Tiib" <ootiib@hot.ee>: Feb 01 06:06AM -0800 > by applying some intelligence and thinking about abstractions, interfaces, class > hierarchies and object hierarchies is, quite frankly, both absurd and possibly > even harmful and I am amazed that you cannot see this. You talk about software architecture. We write tests to test functionality not architecture. It is impossible to write compiling (but possibly yet failing) tests when the architecture elements (IOW interfaces, abstractions and hierarchies) aren't already in place. When it is inconvenient to write tests then it indeed indicates (early) that architecture might be is complicated and non-robust enough and may be worth correcting. > TDD is the totally wrong approach to software development. Design first, > implement second and unit test third. That is orthogonal. For example there is software that will contain about 12 modules, 8 classes in average per module, (so 96 classes) and making one of those classes takes about 3.5 days. Lets say a programmer took a class and implemented it and unit tests for it with 2 days. Who cares in what order he did that? Are we some sort of micro-managers or engineers? |
Cholo Lennon <chololennon@hotmail.com>: Feb 01 11:22AM -0300 > amazed that you cannot see this. > TDD is the totally wrong approach to software development. Design > first, implement second and unit test third. I agree with you. The first time I used TDD (don't confuse with writing a unit test, a common mistake) was in a TDD course that my company sent me. It was really weird. The teacher presented the problem to solve: convert decimal numbers to roman numbers. Well, my group designed and implemented the solution in a few minutes, wrong the teacher said! after that, he explained how we should think and solve the problem using TDD: Start with a simple test that fail. After that add the solution for 1 and test. Add the solution for 2 and test, etc. Try to find a pattern. The iteration process was long because the pattern was changing. It was your first time, the teacher said; future problems will be solved more quickly. I don't know, after several years of trying to apply the technic in C++/Java/Python I'am still unconvinded. The teacher explained that TDD avoids "analysis paralysis" (get stuck in a problem due to overthinking it). You have to think the problem on the fly, try, fail, fix... but IMO most of the time thinking in advance, solves the problem more quickly and with a better design. Regards -- Cholo Lennon Bs.As. ARG |
Ian Collins <ian-news@hotmail.com>: Feb 01 05:04PM +1300 Jerry Stuckle wrote: >>> it's impossible for the scenario to occur in production, anyway. >> So you consume all of the memory on your test box, what then? > Then you test. On a shared development system? Yeah right. >>> 100 times. >> ..and if each call would fetch and parse a file from the internet? > Then it fetches and parses a file from the internet. Evey one of the dozens or hundreds of times a day you run your unit tests? > If a unit test trashes the host or creates a DOS attack on a remote > server, then the test is incorrect or the class fails. If it can happen > during testing, it can happen during production. I don't think you understand the concept of layered testing. The topic of this discussion has been unit testing, not acceptance or system testing. The code being tested may not even be targeted at the system you are developing on (especially if you are unit testing embedded code). The development may not even have access to the devices that are feeding data into the code under test. You have to mock. -- Ian Collins |
Ian Collins <ian-news@hotmail.com>: Feb 01 05:06PM +1300 Alf P. Steinbach wrote: > Well this was called "stress testing", some 15 years ago. > Checking… Yep, still. > https://en.wikipedia.org/wiki/Stress_testing_%28software%29 Exactly: stress testing != unit testing! > impractical. So one measures. And only if the measurements say OK, does > one then assemble the thing and test the complete reality. > Yes? Yes. If the engine is an embedded application, the unit tests are the measurements. -- Ian Collins |
Ian Collins <ian-news@hotmail.com>: Feb 01 05:11PM +1300 Jerry Stuckle wrote: >> So you didn't implement your mock correctly, go back and fix it. > And how do you know if it is implemented correctly if it isn't the full > class? Er, you have a specification? Don't forget a mock is often a simple (even machine generated) piece of code with behavior driven by the tests. > Tell me - how is your mock class going to do the same work as the real > class if it isn't the real class? It's a lot more than just returning a > value from a method call. It isn't. It is going to do what the tests require it to do. If the real code parses a file and returns an object, the mock may simply return a predefined (by the tests) object or sequence of objects. Or if the tests require the mock to throw an exception for a particular test, that is all it will do. -- Ian Collins |
Ian Collins <ian-news@hotmail.com>: Feb 01 05:14PM +1300 Jerry Stuckle wrote: >> by the developers. All of the system and acceptance tests have been >> written by our testers. > Too bad. I'm sure you had a fair amount of bugs in the code. Barely any: manufacturers of embedded systems don't like product recalls which is why we had so many tests. If the process hadn't been effective, it would have been repeated for many years. -- Ian Collins |
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 11:16PM -0500 On 1/31/2016 11:14 PM, Ian Collins wrote: > Barely any: manufacturers of embedded systems don't like product recalls > which is why we had so many tests. If the process hadn't been > effective, it would have been repeated for many years. Manufacturers of operating systems and heavily used applications such as IBM (where I first learned how to develop and test) don't like product recalls, either - and are quite stringent in their testing. Neither are any of the other companies I have consulted for - both as a developer and a project manager. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 11:18PM -0500 On 1/31/2016 11:06 PM, Ian Collins wrote: >> Checking… Yep, still. >> https://en.wikipedia.org/wiki/Stress_testing_%28software%29 > Exactly: stress testing != unit testing! If you need to test a class for out of memory processing, you need to stress test it. >> Yes? > Yes. If the engine is an embedded application, the unit tests are the > measurements. Who said anything about embedded applications? This is the first time it has been mentioned in the whole thread. Are you trying to change the rules again? I see you've tried multiple times so far. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 11:21PM -0500 On 1/31/2016 11:04 PM, Ian Collins wrote: >>> So you consume all of the memory on your test box, what then? >> Then you test. > On a shared development system? Yeah right. You test on a test system. Like all testing should be done. >>> ..and if each call would fetch and parse a file from the internet? >> Then it fetches and parses a file from the internet. > Evey one of the dozens or hundreds of times a day you run your unit tests? If necessary, yes. > you are developing on (especially if you are unit testing embedded > code). The development may not even have access to the devices that are > feeding data into the code under test. You have to mock. Oh, I understand it, all right. I first encountered it as a developer for IBM in around 1982. But once again you're trying to change the topic by bringing up embedded systems. Nothing about embedded systems has been mentioned until you brought it up. But I've seen you're good at trying to change the topic. However, the same is true with embedded systems - at least all of the ones I've worked on as a consultant in the last 25 or so years. And mocking a device is NOT the same as mocking a class other code is dependent on. Do you understand the difference? -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Jerry Stuckle <jstucklex@attglobal.net>: Jan 31 11:25PM -0500 On 1/31/2016 11:11 PM, Ian Collins wrote: > Er, you have a specification? > Don't forget a mock is often a simple (even machine generated) piece of > code with behavior driven by the tests. If the class completely follows the specifications, then it is not a mock class. If it does not completely follow the specifications, you cannot thoroughly test dependent classes. > return a predefined (by the tests) object or sequence of objects. Or if > the tests require the mock to throw an exception for a particular test, > that is all it will do. But if the class has to process a file, then you cannot test it properly unless you process that file. Returning predefined objects or sequence of objects does not properly process the input file - and return the appropriate information. So all you're doing is testing a subset of the possible results. Such a process is always prone to errors. Proper testing would include a real class with real input, both good and bad, and the appropriate processing for all of it. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Ian Collins <ian-news@hotmail.com>: Feb 01 05:38PM +1300 Jerry Stuckle wrote: >> feeding data into the code under test. You have to mock. > Oh, I understand it, all right. I first encountered it as a developer > for IBM in around 1982. I don't think you do, otherwise you would realise the difference between unit and system testing. You most certainly do not want your unit tests to stress test your development system, or do anything that consumes significant time or resources. Unit tests should run as quickly as possible, if the take too long to run, you will back off running them. I develop with "make" = "make test", so my unit tests are run for ever code change. > But once again you're trying to change the topic by bringing up embedded > systems. Nothing about embedded systems has been mentioned until you > brought it up. But I've seen you're good at trying to change the topic. That's a poor strawman, there was no change in topic. I could just as easily substituted any piece of software. Note I said "especially if you are unit testing embedded code" not "only if you are unit testing embedded code". Embedded code is simple an extreme example of something you wouldn't unit test on target. > ones I've worked on as a consultant in the last 25 or so years. > And mocking a device is NOT the same as mocking a class other code is > dependent on. Do you understand the difference? From the perspective of software other than its driver, a device is a class other code. Device driver tests use mock hardware, the code that uses driver class mocks the driver class and so on up the stack. -- Ian Collins |
Ian Collins <ian-news@hotmail.com>: Feb 01 05:48PM +1300 Jerry Stuckle wrote: > If the class completely follows the specifications, then it is not a > mock class. If it does not completely follow the specifications, you > cannot thoroughly test dependent classes. You can (and thousands of us do) because it *pretends* to implement the specification. I suggest you do some research on mock objects and how they are used. >> that is all it will do. > But if the class has to process a file, then you cannot test it properly > unless you process that file. Quite - because you aren't testing it! You are testing the code that process the resulting object. > of objects does not properly process the input file - and return the > appropriate information. So all you're doing is testing a subset of the > possible results. Such a process is always prone to errors. You've lost the plot, *we are not testing the file processing*. We are testing the processing of the result of the file processing. > Proper testing would include a real class with real input, both good and > bad, and the appropriate processing for all of it. Indeed it does, but not unit testing something that has no interest in how those files are processed. I've said it before but it bears repeating: layered testing. -- Ian Collins |
Paavo Helde <myfirstname@osa.pri.ee>: Feb 01 09:52AM +0200 On 1.02.2016 1:50, Jerry Stuckle wrote: > If you don't test the independent class first, you have no idea where > the problem lies. And as you get more and more classes involved the > problem becomes more difficult. The debugger will show me where the problem lies. But you are right, if there are separate tests it would be easier to pinpoint the problem. For example, if after some unrelated change 10 tests start to fail, among them the tests for A and B, then it makes sense to start with B and its test as B is the simplest class and likely the core of the issue. > The design will define the class dependencies. And every time you have > to rewrite A to adapt it to be, you are wasting programmer time, test > group time, and potentially inserting more bugs. The code is changing every day because of the changing requirements, changing priorities, changing environment, etc. You cannot design everything up-front. The extensive automated test suites are there exactly for allowing to change, adapt and refactor the code base without the fear of introducing new bugs. Ideally, the codebase would become wax instead of layers of petrified sediments. It is very easy to reshape wax. > A proper design means the independent classes can be written first, and > the dependent ones later. This eliminates the need for programmers to > rewrite dependent code. Agreed - if you can get the design 100% right before starting the coding it would be perfect. However, in my experience this rarely happens, and even then there would be later changes because of unforeseeable factors. |
David Brown <david.brown@hesbynett.no>: Feb 01 11:31AM +0100 On 01/02/16 00:55, Jerry Stuckle wrote: >> include testers. > Not a chance. Never in any of the major projects I've been involved in > have any tests been performed by the developers. Our systems and integration test people would be pretty annoyed if our developers handed them code that had not been tested. Do you think developers just write some code, see that it compiles without warnings, and say "give that a shot and see if it works" ? Before passing code on to the next layer of testers, the developers will do everything practically possible (using TDD, unit tests, automated test benches, simulations, whatever) to ensure there are no known bugs and their tests are as complete as possible. |
"Öö Tiib" <ootiib@hot.ee>: Feb 01 03:37AM -0800 On Sunday, 31 January 2016 23:44:29 UTC+2, Ian Collins wrote: > Doesn't anyone have colleagues any more? Sorry, I just hate the term > "coworkers"! No! Colleagues still win 200:19 http://www.googlefight.com/coworker-vs-colleague.php The term I typically use sounds root-by-stem translated as "workfellow", "workmate" or "workpartner". Only "workmate" is what I have actually heard said in English. Sorry, if I translate it sometimes as "coworker". |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 01 11:22AM When a computer downloads a web page, the computer is called »client« and the source of the download is called »server«. When a function »m« calls another function »f«, we call »m« a »client« of »f«, but how to we call »f« then? One does not call a function a »server«, does one? |
Juha Nieminen <nospam@thanks.invalid>: Feb 01 09:20AM > 'int' considered dangerous: use a <cstdint> sized integer typedef instead. It depends on what you are doing. If you are writing a library that should be as portable as possible, and expected to be used in wildly different platforms, from ols small embedded systems to modern 64-bit processors, then perhaps. If, however, you are writing closed-source software for a specific platform (let's say, for example, iOS), then it might even be better to use int for integers whose maximum size is irrelevant. On that particular platform you can be sure that int will have a minimum size and will never get smaller even in future versions of that platform, so you'll be A-ok. Why use int instead of an equivalent std type? Because 'int' is ostensibly always the most efficient integral type of the system, even in future versions of the platform. You'll never know if the std type you chose will be the most efficient in a future version. > On a related matter eschewing unsigned integer types is foolish as one > should use an unsigned type when dealing with unsigned values. unsigned causes problems when it's mixed with signed types. And this happens quite easily. Example: Image size cannot be negative. Negative values are nonsensical. Therefore it makes sense to use unsigned to store image dimensions? In theory yes. In practice you'd better use a signed type because image coordinates *can* become negative in many situations (eg. line drawing, or sprite coordinates), and you'll run into problems when mixing signed coordinates with unsigned image sizes. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
Derwin Crummel <dwc@nowhere.invalid>: Jan 31 03:56PM -0800 Found this function in application code for a NNTP client. Errors are marked below. Clearly, the iterator is mis-applied here but how to fix? int TArticleBank::CreateArticleIndex (TArticleIndexList * pIndexLst) { ASSERT( pIndexLst ); CSingleLock sLock(&m_crit, TRUE); // RLW - only call PuntLinkInformation if there are articles to move to m_setNodes if (GetCount() > 0) { // move m_Stage to m_setNodes PuntLinkInformation (); } // Note: flat list is created during Link(). So go directly(!) to // the m_setNodes STLMapArtNode::iterator it = m_setNodes.begin(); while (it != m_setNodes.end() ) { TArtNode * pNode = *it++; //error C2440 ASSERT(pNode); pNode->CreateArticleIndex ( pIndexLst ); } return 0; } //------------------------------------------------------------------------- int TArticleBank::Empty () { CSingleLock sLock(&m_crit, TRUE); ASSERT(m_Stage.size() == 0); m_Stage.clear(); STLMapArtNode::iterator it = m_setNodes.begin(); while (it != m_setNodes.end()) { TArtNode * pNode = *it; //error C2440 // delete call (1/3) delete pNode; it++; } m_setNodes.erase (m_setNodes.begin(), m_setNodes.end()); m_ids.Empty(); delete m_pMyViewFilter; m_pMyViewFilter = 0; return 0; } error C2440: 'initializing' : cannot convert from 'const ob_artnode_ptr' to 'TArtNode *' |
Victor Bazarov <v.bazarov@comcast.invalid>: Jan 31 07:31PM -0500 On 1/31/2016 6:56 PM, Derwin Crummel wrote: > TArtNode * pNode = *it++; //error C2440 > ASSERT(pNode); > pNode->CreateArticleIndex ( pIndexLst ); A set (if 'm_setNodes' is declared as 'std::set') contains *constant* objects. Once they are inserted, they are not subject to any mutation. You can pull it out, mutate it as you please, then reinsert it. > while (it != m_setNodes.end()) > { > TArtNode * pNode = *it; //error C2440 Same idea. You can't get a mutable object that retains its position in the set. If you need to remove it, then remove it (using .erase(it)), get the iterator that it returns, and then do what you want with the pointer. Perhaps you should consider storing smart pointers in that set. When removed from the set, they will destroy the object they point to. > } > error C2440: 'initializing' : cannot convert from 'const > ob_artnode_ptr' to 'TArtNode *' V -- I do not respond to top-posted replies, please don't ask |
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