home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,611 of 33,346   
   Ivan Godard to All   
   Fwd: Re: Useful applications for boolean   
   25 Oct 12 11:31:48   
   
   From: igodard@pacbell.net   
      
   >   
   >   > I frequently use increment over an enumeration, typically when   
   >   > iterating over an array whose index set is an enum. This construct   
   >   > is not native to C/C++, but with type traits that give lower/upper   
   >   > bounds for enum types and a little meta-programming you can write:   
   >   >      enum E(f, g, h);   
   >   >      array a, b;   
   >   >      forEach(x, thru()) {   
   >   >          a[x] = 17;   
   >   >          b[x + 1] = 23;   
   >   >          }   
   >   
   >   > The metaprogramming ensures that a[5] is illegal. ++ and -- are   
   >   > defined as the successor and predecessor operations in the natural   
   >   > way, as are E ± integral and E - E (but of course not E + E) in the   
   >   > obvious way.  That is, the set of arithmetic operations are the   
   >   > same as for pointers.   
   >   
   > I agree that this looks like a useful tool. Am I correctly   
   > understanding that this is a view of an enumeration type's range of   
   > valid values (specified by the extreme values b_min and b_max in the   
   > standard)?   
      
   Strictly speaking it is defined by the lwb and upb values supplied to   
   the macro that sets up the traits for the enumeration, and could be any   
   value coerceable to a constexpr of the enum. In practice they are always   
   the extrema of the declared values of the enum's list. Neither I nor a   
   Google search are familiar with std::b_min/max.   
      
   It would be very nice if these extrema and some of the other information   
   well known to the compiler but hidden by the language were exposed to   
   the user, instead of requiring manual maintenance of traits. The most   
   badly needed IMO is an array of strings containing the printnames of the   
   enumerates.   
      
   >   
   >   > Now all this is to patch the monstrosity that is enum in C. The   
   >   > relevance to your question is that, in any reasonable semantics,   
   >   > type bool would be an enum{false, true} and not an integer. We   
   >   > actually support use of bool instead of an enum in the above   
   >   > constructs, but the metaprogramming to do so is painful.   
   >   >   
   >   > Consequently I would suggest that rather than make bool even more   
   >   > of a special case by removing ++, you should instead fix enum and   
   >   > make bool an instance thereof.   
   >   
   > 1) What I don't quite see is: Why is this a fix of enumeration types?   
   > Unless I misunderstand what you are suggesting, this change would only   
   > have the effect do add a concrete enumeration type to the library. I'm   
   > assuming that means that type bool is added as some concrete   
   > enumeration type to the global namespace. Will there also exist a type   
   > bool in namespace std (Actually all library components are within   
   > namespace std, such as std::nullptr_t)?   
   >   
   > 2) Assuming that I correctly understand you, this would transform type   
   > bool into an otherwise completely normal enumeration type. This would   
   > have the effect that e.g.   
   >   
   > int i = 13;   
   > bool b = i;   
   >   
   > would no longer compile. Assuming you solve this (somehow) other   
   > examples like   
   >   
   > double d = 1e29;   
   > bool b = d;   
   >   
   > would now have undefined behaviour, because it falls under 4.9:   
   >   
   > "The conversion truncates; that is, the fractional part is discarded.   
   > The behavior is undefined if the truncated value cannot be represented   
   > in the destination type."   
   >   
   > It would also mean that now   
   >   
   > void test(int* p) {   
   >      bool i = p;   
   > }   
   >   
   > would no longer compile. Same thing for member pointers. This would   
   > also mean that you could no longer specify that the value of a   
   > condition within a statement (like 'if' or 'while') is type bool,   
   > because when you still do so, other popular idioms like   
   >   
   > void test(int* p) {   
   >      if (p) { ... }   
   > }   
   >   
   > would no longer work (because you cannot implicitly convert a pointer   
   > value to an enum value). Would these be considered as   
   > reinterpret_casts to bool, instead?   
   >   
   > Now I'm pretty sure that you don't want to ban all these code   
   > examples, therefore this looks to me as if you would need to define a   
   > lot of extra rules that say: "Well, bool is actually an enum, but   
   > ...".   
   >   
   > This sounds like a model to me, that initially would introduce several   
   > unresolved problems to the core language. Could you elaborate a bit   
   > more on your proposal to give some directions how to solve these side   
   > effects of such a change?   
   >   
   > Thanks && Greetings from Bremen,   
   >   
   > Daniel Krügler   
   >   
   >   
      
   There are two issues being confused here. My concern is functionality or   
   lack thereof. The second is the legacy of C and its lack of   
   functionality that would treat an enum as more than the collection of   
   #defines that was all C had at the beginning.   
      
   I have strong opinions regarding the functionality, and our code goes a   
   long way toward making the enum concept useful via some tortuous   
   metaprograming and traits classes. I can and have offered the improved   
   functionality to the language.   
      
   In my day I have been a language lawyer - my name is in the Algol 68   
   revised report - but I am certainly not familiar with the C or C++   
   standard to the degree needed to suggest modifications without grave   
   unintended consequences. However, I'll do my best to respond to your   
   questions regarding the language and syntax legacy.   
      
   K&R C, and BCPL before it, had only fixed integer for a data type, at   
   most 16k for compiler and source, and a strong aversion to   
   carpal-inducing Model33 teletype key presses. Everything was an integer   
   and terse beyond reason.   
      
   The present language contains legacy cow flops from that distant day.   
   Among other holdovers is the use of zero as a null pointer, the elision   
   of "if (foo == 0)" to "if (foo)", and the coercion rules for bool and enums.   
      
   All of these idioms are deprecated in our code. They are removed in code   
   reviews and in some cases by tools or metaprogramming. Heightened   
   readability results: if you see "if (foo)", then you know that foo is a   
   boolean variable, not a pointer. If you see "switch(foo)" you can be   
   confident that all the case labels are actually enumerates of the class   
   of foo and not some other enumeration or some macroed integer. And so on.   
      
   Recently the standard took some halting steps toward cleaning up the   
   zero-as-null issue, and introduced enum class so at least spurious name   
   collisions among enumerates could be avoided. Kudos. Unfortunately, we   
   now have yet more half measures that merely complicate compiler and mind   
   without being functional.   
      
   I do not believe that it would be possible or desirable to eliminate the   
   legacy idioms you list, breaking billions of lines of code. I feel that   
   the only pragmatically possible solution is to introduce a new properly   
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca