I'm a bit puzzled at your response, as you seem to be addressing C/C++ rather than Java? I've probably contributed to the confusion by talking a little bit about C++ vs C. Perhaps you intend your response to just refer to some aspect of those remarks?
But let me try to sort it out by context. You're clearly talking about C/C++ code -- everywhere. This discussion is about Java code. But let me address the C++ issues you raise, first. C++ does provide a useful point of comparison and contrast. I'll then contrast each point with Java. First, there is no trade-off between virtual / non-virtual vs macro. Macros are entirely compile-time, and so are non-virtual calls. Whatever you're doing with macros, you can do without virtual method calls. With Java, we don't have the same distinction between virtual and non- virtual. We do have a performance difference between private and package-private (default) vs protected and public. I don't think there's anything useful you can do with macros to really enhance performance here -- certainly not worth the complexity. If adding some classes seriously makes your project more complex, then it's likely your class hierarchy isn't well-designed. This was a common problem with a lot of early UI frameworks -- for example, MFC. A well-designed class hierarchy actually helps you break your project files up according to functionality. But early on in the world of object-oriented program, everyone tried to do everything through inheritance. It turns out, this isn't a good idea. Inheritance is good, but so is delegation and collaboration, and a good design will use these together to keep contracts tightly focused. Inheritance works better when used with a well-factored collaboration of objects, and collaboration works better when when key objects can be separately specialized via inheritance. There ARE some costs to debugging virtual method calls because you don't know statically what method will be called, but we're talking about static calls here, if we're comparing what you can do with macros vs class hierarchy. Let's say the differences you want to deal with are related to platform. A better approach than scattering conditionals or even function-like macros through your code, are to segregate those platform differences into a Platform class. Methods on this class can be in-lined. This is better than a macro -- FAR better from a debugging standpoint, because macros always obscure what code you're debugging. You can do the same thing with Java. And, with tools like ProGuard, you can even get the benefit of inlining. And I disagree about counting on the optimizer. Optimizers optimize things that humans pessimize. Humans really aren't very good at optimization. Oftentimes, humans make the mistake of inlining blindly, and bloat the instruction cache, resulting in WORSE overall performance. And the human effort spent toward small optimizations like this is better spent focusing on making the basic approach more efficient, or other more productive tasks. In Java, the optimization conditions are well-defined. The conditions under which IF can drop unreachable code are even part of the specification, at least partially. ProGuard can go beyond that, because it allows you to make global assumptions about what code will be used together. I didn't say that C++ was entirely successful in its goal of eliminating the need for macros or conditional compilation. In addition to your example of the assert macro, there's also the example of header file guards. But the need for header file guards is entirely due to the presence of macros in the language! Otherwise, the compiler could simply skip redundant headers, and the ordering of includes wouldn't matter. And, in fact, that is exactly the situation with Java. The order of imports can and should be entirely based on readability. We lack any equivalent of __line__ and __file__, but our stack traces generally have that information, unless we decide to do away with it to save space. And back to the trade-off of complexity -- since Java and Java tools assume there is NOT a preprocessor, you're always introducing a SUBSTANTIAL element of complexity, with the very first use of preprocessing. Further, C/C++ macros result in a huge number of bugs. This is a HUGE problem -- you probably have gotten so used to it you don't notice. Somebody defines a macro somewhere in a header file, and it breaks some code that doesn't even use that macro, because it indirectly includes some other header file, that doesn't use that macro either -- but does use a local variable that happens to have the name of that macro. People spend HOURS sorting these things out. I've had to teach GENERATIONS of programmers how to track down such problems, because usually they're absolutely baffled. And how to do it, exactly depends on the toolset you're using. And even when you know, it's a royal pain, because of all the unreadable preprocessed CRAP you have to sort through. Now, about whether Microsoft, Google, and Linux can be getting it wrong: Well, let's look at that. First, stdlib.h is a C library. It has to work with C. It's not even recommended to use with C++ if you can avoid it! One of the biggest reasons for the use of macros in C++ is compatibility with C. That applies to Microsoft headers, and Linux headers. I don't know if Android includes much C code above the OS level, but the JNI interface at least supports C. Microsoft's STL implementation, at least the last time I seriously looked at it, was of EXTREMELY poor quality. I would both guess and hope it is vastly improved by now, but my point is that Microsoft certainly CAN get stuff wrong. Ignoring all the myriad violations of the standard -- Microsoft's implementation of std::string was not only not THREAD safe -- it was not even DLL safe. (A lack of DLL safety is something I've never encountered ANYWHERE else!) Under some circumstances, passing a std::string from code in one DLL to another would cause failure. The stl classes would often have to be carefully ordered -- sometimes incompatibly with the order imposed by OTHER platforms -- to avoid macro conflicts with various system header files. As for Linux? Well, the kernel is in C, not C++. Even if you're talking about C++ code in the context of Linux, this drives the overall outlook and expectation. But a well-done C++ project will seek to minimize the use of macros and conditional compilation, and reap great benefits by doing so. The C legacy will still bite you once in a while, but to the extent you can isolate OS dependencies in a few platform-specific files, you'll contain and minimize these problems. Another aspect I've observed is that the problems with C macros and conditional compilation tend to grow with time. They don't seem so bad at the start of a project. As a project grows and matures, however, and as it is ported to an ever longer list of platforms, the problems become worse and much harder to deal with. By the time you port to Windows (several versions), Macintosh, a dozen flavors of Unix and Linux, things will have gotten very much out of hand, if you haven't taken steps to address the issue by isolating platform dependencies. Have you ever worked on a body of C/C++ code that was 15 years or more old? These sorts of issues arise MUCH less in Java. A part of that is because Java doesn't have preprocessor macros and conditional compilation, and so doesn't have platform or environment differences in those areas. The other big reason is that Java offers a lot of cross-platform facilities. However, differences do arise on occasion, dealing with things like filesystem layout, availability of third- party libraries, Java version (Apple lags seriously behind on Java version -- as does Android), etc. So while the problems are less, the same solutions of isolating platform dependencies still prove valuable in large projects. (Small projects may not encounter enough differences to be worth any measures -- often none at al). There's always room for improvement in software projects. Just because you find a technique used in some projects doesn't mean it wouldn't be better with a different technique -- and often this would be strongly acknowledged by the authors themselves. Sometimes it's just too hard to change from the course you're already on. And this is even more true when there are factors working against you -- such as the prevalence of C interfaces in C++ code. I think it's fair to say that despite the standard encouraging people to use better techniques, few C++ projects completely eschew conditional compilation and preprocessor macros. As a final note, I'll point out that the problem with C macros are not true of all types of macros. C preprocessor macros are particularly nasty because they are non-syntactic. They violate the language's own syntax. The C++ preprocessor cleans this up a little bit, but only a bit. They combine this with extremely limited power. I'm not down on macros as a class -- I met my wife while teaching a class on Macros in Lisp back in 1992. There are definitely times I miss having Macros in Java -- but C macros would almost never satisfy those needs anyway. By contrast, with XSLT, you do very powerful transformations on XML, and you can even generate Java code from XML fairly cleanly and reliably -- and then be able to work with the XML using any XML tools. Android chose the approach of generating small bits of Java from XML, rather than processing Java to get the same information. They could have used Java annotations, but this approach has many benefits -- centralizing this information, making it easier to customize for locale and configuration, the ability to work with it using any XML toolsets, etc. Every use of preprocessing in Java that I have worked with over the years has soon been replaced, with something better that did not involve preprocessing. So have some uses of code generation -- but not all. Code generation appears to be a more robust and less problematical approach. To the extent that code generation is a viable alternative to preprocessing, it is definitely to be preferred. That also applies to C/C++, BTW. Data-driven code generation presents fewer problems than the ubiquitous-but-problematic preprocessor. On Apr 2, 7:01 pm, Emmanuel <[email protected]> wrote: > Interesting... > > Working for some years on multiplatform / multi compiler big > performance sensitive projects( console games actually), I always find > that macro / conditional compilation WAS the consensus ! > Using this for distinctions between platform specifics + version > specific + switching between several versions of the code is soooo > common ( but, obviously, not the only used tool ) > In no way I'm saying we're using this in all situations : we can have > distinct specific code in several libraries or different per platform > implementation files or using interfaces... But there are many cases > where I honestly think macro use is the very best situation... > > Using interfaces adds unnecessary virtual that are really costy on > some processors. > Adding some classes make the project more complex to handle, read, > debug, maintain... Using too much macro also make the project more > complex to handle / read / debug / maintain, so you have to find a > balance between those two... > As much as we can, we try to maintain a good level on performance on > the debug versions too, in order to have them usable in the first > time, so counting on the optimiser is not a good idea ! > We have a assert macro that makes use of the __line__ and __file__ > special symbols > ... > > Beside that, I tried to open some files given with my compiler ( here > at home, so it's Visual C++ Express 2005 ) : stdlib.h, stl > implementations, etc... > They contain macro usage... > I looked into Android C++ code ( this is an android ML after > all :) )... And find macro usage... > Looked into linux sources... and find macro usage... > > I'm quite suspicious thinking both My projects AND microsoft + google > + linux developers all get it so wrong... > > Emmanuelhttp://androidblogger.blogspot.com/http://www.alocaly.com/ > > On Apr 1, 6:28 pm, Bob Kerns <[email protected]> wrote: > > > > > My first response was to say "OF COURSE YOU CAN!" -- but then I > > realized you must be talking about including or excluding data > > members, rather than the actual data. > > > All I can say is, if you're doing that in C++, you're doing it wrong, > > and you should read up on object-oriented design patterns. > > > C++ goes out of its way to make #ifdef unnecessary. But a lot of C++ > > programmers come from a C background, or read a lot of C in the > > process of learning C++, that they never learn to properly use it. It > > doesn't help that the language is insanely complicated, and it takes a > > LOT of time and effort to become really proficient. > > > Adding or not adding fields and methods to classes should be handled > > through subclassing and/or interfaces. And you should consider > > refactoring into collaborations of separate objects, rather than large > > flat classes. > > > Guy Steele, the author of the Java standard, cowrote a popular book on > > C, and was a key member of Tartan Laboratories, which created > > optimizing C compilers for a wide range of platforms. James Gossling > > had a huge amount of C experience as well, implementing Gossling > > Emacs, and of course, Java. Hell, Guy used to write maintain a huge > > amount of ITS PDP-10 macro assembler, code that I also worked on as > > part of the same group at MIT, so I can say with absolute certainty -- > > the designers of the Java language and its standard are VERY aware of > > conditional compilation, and the reasons it is not in the language are > > to make it a better language. > > > I can also speak from my own personal experience. It's hard to > > quantify my C/C++ experience, but it goes back to the 1970's, long > > before there was even a dream of C++, and Java since relatively soon > > after it came out in 1995. I've mentored a lot of people both in C++ > > and Java. I've also participated in language standardization efforts, > > maintained and written compilers and language runtimes. > > > Now, all that constitutes "argument by authority", and proves nothing, > > of course. But I'm not trying to get you to switch off your mind and > > just believe what I'm telling you. On the contrary -- when there's a > > consensus of experts, you should poke around, kick the tires, explore, > > try things, look for counter-examples, etc. > > > One of the best type of counter-example is "X is a real gain of time", > > as you put it. My guess is that it's a gain of time for you because > > you're not familiar with other techniques, but if you'd like to post a > > more concrete example, we can discuss it and alternatives. > > > I won't waste your time with examples of how conditional compilation > > can waste your time, as the solution is generally "don't use it that > > way". > > > But I'm generally in favor of things that save you time. Sometimes, > > even things that save you time up front but cost you more time later. > > > On Mar 31, 4:50 pm, Emmanuel <[email protected]> wrote: > > > > Waooo... > > > > I think you are a little bit expeditive on this one ! > > > > I really think #ifdef are a very important thing in C / C++, and I > > > missed so much in any other languages I am using ! > > > > Using static / constant data can't achieve the same thing : for > > > instance you can't have different data in a class without ifdef... > > > It makes programs more difficult to read, but you really can switch > > > from different versions of your programs much more easily, and it's a > > > real gain of time ! > > > > Emmanuelhttp://androidblogger.blogspot.com/http://www.alocaly.com/ > > > > On Mar 30, 12:36 pm, Bob Kerns <[email protected]> wrote: > > > > > You do not do that in Java. > > > > > I suggest you should not do that in C++, as there are better ways to > > > > do it. > > > > > I suggest you do not use C. > > > > > On Mar 30, 2:57 am, Dilip Dilip <[email protected]> wrote: > > > > > > Hi All, > > > > > How to do conditional compilation in JAVA. > > > > > > something like in C, C++ : > > > > > > #ifdef TRUE_CONDITION > > > > > > #else > > > > > > #endif > > > > > > Thanks and Regards, > > > > > Dileep -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en To unsubscribe, reply using "remove me" as the subject.

