3

What's standing in the way of new operators added to the C/C++ standard, such as <<< and >>> for bitwise left and right rotate operations? Is there a reason why the standards organizations can't include such operators in a future spec?

I know there are other ways to accomplish this:

  • & >> | << combo
  • Intrinsic functions
  • Inline assembly

The problems with these workarounds are:

  • Performance
  • Readability
  • Potentially more complex code generation
  • Platform/compiler dependence

To me, this seems like an inconsistency. If they are already making the effort to provide simple, readable, high-performance operators for & | ^ << and >>, bitwise rotate operators shouldn't be any more difficult to support for 8-, 16-, 32-, and 64-bit signed/unsigned values.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Giffyguy
  • 20,378
  • 34
  • 97
  • 168
  • 2
    What on earth is a "high-performance operator"?! – Kerrek SB May 29 '15 at 23:44
  • 2
    I agree with you 100%. Their omission is simply because the PDP-11 didn't have those opcodes. Times have changed. – StilesCrisis May 29 '15 at 23:46
  • @KerrekSB An operator that translates to 1 or 2 assembly commands, rather than a function call or other unnecessary bloated mess (I'm looking at you, Java). – Giffyguy May 29 '15 at 23:47
  • 11
    GCC, Clang, and many other compilers are smart enough to recognize `(a << 1) | (a >> 31)` and compile the single-instruction rotate. – Lee Daniel Crocker May 29 '15 at 23:47
  • 4
    All compilers I use and have used in the past decade seem to be doing just fine with idiom recognition for rotates, which is why there is probably not a lot of pressure on (and lack of proposals to) the relevant standards committees to define new operators. I agree new operators would improve readability, if only slightly. – njuffa May 29 '15 at 23:48
  • @LeeDanielCrocker Yeah, and that's nice. But it's still a dependency on the compiler that isn't standardized. How can we be guaranteed that this will work in all compilers? – Giffyguy May 29 '15 at 23:48
  • 1
    @Giffyguy As stated, "why doesn't C have this", answers will be pretty broad and opinion-based. If you edit your question to simply ask why K&R didn't include it in the original design, there's the potential for factual (and interesting) answers. – MooseBoys May 29 '15 at 23:50
  • @MooseBoys Point taken. It is getting a few upvotes though, so apparently I'm not the only person annoyed by this. Maybe I'll start a petition somewhere. :) – Giffyguy May 29 '15 at 23:53
  • 2
    Because the PDP-11 didn't have a multi-bit rotate operator. – Hot Licks May 29 '15 at 23:59
  • 3
    @HotLicks: see [the persistent myth of the PDP-11](http://cm.bell-labs.co/who/dmr/chist.html): "This is historically impossible, since there was no PDP-11 when B was developed." (The design of C is based on B) – Jongware May 30 '15 at 00:36
  • 7
    [It has been recently proposed for C++ and rejected](http://cplusplus.github.io/EWG/ewg-complete.html#123). – T.C. May 30 '15 at 00:49
  • lol, if this question keeps getting closed and reopened over and over as people keep voting both ways, I might just have to add a bounty in a couple days. :) – Giffyguy May 30 '15 at 00:49
  • 1
    @Giffyguy Petitions won't do any good, you would want to submit a well-reasoned proposal to the relevant standard committee (e.g. http://www.open-std.org/jtc1/sc22/wg14/ for C) and gather support among current committee members. On their web site you can find several worked examples, e.g. this proposal to add decimal floating-point support: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1312.pdf – njuffa May 30 '15 at 00:51
  • 1
    There is no pressing need for having native C support for *all* possible opcodes (and for all possible CPUs, as there are vast differences between the supported opcode sets). What about `abcd` and `sbcd`, for example? Binary encoded decimals are still used, but they don't even have a native C type of their own. – Jongware May 30 '15 at 00:51
  • @T.C. Thanks for the link. That looks like a well-worded proposal. This language cheeses me off, because they don't explain their position (as far as I could see). "EWG was unanimously against having an operator for this ..." – Giffyguy May 30 '15 at 00:56
  • 1
    I would argue that rotates are much more common in C/C++ software than the use of binary code decimals. Opinions on prevalence will differ based on personal experience. Because this question invites opinionated discussions on various aspects of the question, I have voted to close it as unsuitable for Stackoverflow. – njuffa May 30 '15 at 00:56
  • @Jongware - Well the PDP-7 EAE didn't have multi-bit rotate either. – Hot Licks May 30 '15 at 00:56
  • 1
    @Giffyguy: I have not worked with those committees, but am aware that rationale is apparently tracked in separate documents. For example there is a lengthy document spelling out the reasons for all changes made when going from C89 to C99. – njuffa May 30 '15 at 00:58
  • 1
    @HotLicks: true. If only C was artificially limited to use its "standard memory capacity [of] 4K words (9 kB) but expandable up to 64K words (144 kB)" as well. Now *that* would teach those lazy programmers of to-day a lesson. – Jongware May 30 '15 at 00:58
  • @Jongware Hyphenating "today" is considered archaic. :-) – ooga May 30 '15 at 01:10
  • 4
    Rotate is just part of the deal. What is sorely missed is a carry. I want rotate through carry. I _need_ add with carry, for Cray' sake! – user58697 May 30 '15 at 01:11
  • @user58697 There are architectures without a carry flag, e.g. MIPS, so it seems to make little sense to introduce the concept into C/C++. What do you *need* the carry flag for? – njuffa May 30 '15 at 01:16
  • @Giffyguy: That doesn't make sense. There are no "assembly commands" in the C++ language, and you can't standardize implementation. Even if you had such an operator, there'd be nothing guaranteeing an efficient implementation. You *always* have to trust your compiler to generate good code. And if you do, then you're already done. I agree that it'd be nice to standardize some of the more specific bit functions like rotate and popcount, but I don't see the need for an actual operator. – Kerrek SB May 30 '15 at 10:37
  • @KerrekSB Thanks for the insight, and I agree with you. However, I think you may be reading too far into my "high performance" statement. The workarounds I mentioned in the original question are frequently just as performant as any single operator would be, so long as the compiler generates good code - as you said. However, the following statement of yours is short-sighted IMHO: "And if you do, then you're already done." No, it's not done, because my code still looks like crap. :) That's the central painpoint being addressed here. – Giffyguy May 30 '15 at 16:13
  • 1
    @njuffa I expected that. I need carry for algorithms for which it is natural, big integer-like calculation, for example. If it is not available, I can emulate it no problem. But why should I pay emulation penalty where it _is_ available? The compiler is in much better position to chose between hardware caps and emulation. – user58697 May 30 '15 at 17:54
  • @Giffyguy The reference to LWG (the library working group) suggests that they believe this should be a library feature. Introducing a new operator is a much bigger change than a library function. (The technical specification in that paper is missing quite a few things, for instance. At a minimum, you need to add new tokens to the lexer, and solve the right angle bracket problem again with `>>>` so that `vector>>` is parsed correctly.) – T.C. May 30 '15 at 21:20
  • @T.C. I hear ya there, but that doesn't sound insurmountable to me. Seems like a somewhat weak excuse. After all, they already had to solve the same angle bracket problem for `>>`, so the solution here would just be an extension of the existing solution to that problem. Perhaps I value consistency and readability more than avoiding the trouble of introducing a new operator, and I can understand if the committees see it the other way around. – Giffyguy May 31 '15 at 06:05
  • @Giffyguy It's not impossible to solve, of course. They just decided that the benefit's not worth the cost. – T.C. May 31 '15 at 06:14
  • 2
    @Giffyguy Incidentally, the angle bracket problem is harder than that. `if(A>>=1)` is `if(A> >= 1)` right now, which is perfectly valid code if `A` is a variable template. If you don't break apart `>>>=`, it will break existing code, and if you do then you have to decide what to do about `>>=` and the like (current rules don't "break apart" `>>=`), and either create an inconsistency, or risk breaking other code. I'm sure someone can come up with a solution if they work really hard on it, but it's tricky. – T.C. May 31 '15 at 06:15
  • @T.C. Wow, you're right. I was laboring under the assumption that backwards compatibility with older code would not be such a major issue. That makes it much more difficult to implement this operator. – Giffyguy May 31 '15 at 06:26
  • For the record: best-practices for expressing rotates in a compiler-friendly way, with no undefined behaviour: http://stackoverflow.com/questions/776508/circular-shift-rotate-operations-in-c. – Peter Cordes Aug 17 '15 at 17:29

0 Answers0