Coding Style Question - Is there any sane reason for doing this?

49 views
Skip to first unread message

BCFD36

unread,
Jan 9, 2012, 8:11:00 PM1/9/12
to
I am working on a piece of legacy code that has many, shall we say,
strange things. This one, as J.K. Anderson (classics Prof at UC
Berkeley) used to say, "baffles me". It has the following statement in
the code:

const unsigned int WAKEUP_MASK = (1 << 1) ;

Is there any reason for doing this, other than to make the code even
more obscure?

D. Scruggs

Alf P. Steinbach

unread,
Jan 9, 2012, 8:23:07 PM1/9/12
to
No, there is no good reason: one should in general reserve ALL UPPERCASE
identifiers for macros.

But they should be used for macros.

Also, there is no reason for the keyword `int`.

So that's also quite baffling: is the author, like, a compulsive typist
who just wants to type as much as possible, regardless of lack of meaning?

Anyway, the almost OK part of that code, `1 << 1`, explicitly tells you
that this is a single bit bitmask, and which bit is set; in the context
of the rest it's bafflingly clear & communicative. It's generally good
to be explicit in code, and let the compiler handle the translation to
machine code, rather than doing it oneself and writing e.g. 0x0002. The
latter is just a number which the reader then must decompile. However,
for the general case `1 << n` runs the risk of Undefined Behavior, since
it is a signed expression. It should be `1u << n`.


Cheers & hth.,

- Alf

Ian Collins

unread,
Jan 9, 2012, 8:30:25 PM1/9/12
to
In addition to Alf's comments, the form is quite common especially in
the embedded or driver world. Although it is more common to see
something like

const unsigned wakeupBit = 1;
const unsigned someOtherBit = 2;

// other bit definitions

const uint32_t wakeupMask = (1u << wakeupBit);

--
Ian Collins

BCFD36

unread,
Jan 10, 2012, 12:32:47 AM1/10/12
to
Interesting. I didn't know the form is common. I've never seen it
before, but I don't do much driver work and haven't seen it in the
embedded work I have done.

Personally, I find it quite obscure and prefer the 0x0002 notation
myself. But I will have to think on it some more. I can see how you
could OR together a bunch of these and it be pretty clear which bits are
set. But I still find it obscure.

Thanks, much. Just for grins, I think I'll run it by the rest of my
group and see if any of them have seen it before.

--
Dave Scruggs

Richard

unread,
Jan 10, 2012, 1:05:18 AM1/10/12
to
[Please do not mail me a copy of your followup]

"Alf P. Steinbach" <alf.p.stein...@gmail.com> spake the secret code
<jeg3u2$fen$1...@dont-email.me> thusly:

>No, there is no good reason: one should in general reserve ALL UPPERCASE
>identifiers for macros.
>
>But they should be used for macros.

I've seen people defining constant quantities like this in upper case
because they are used to only being able to define constants with
macros and they've equated the semantic category of "constants" to
"macros" in their mind.

I could go either way about it.

I prefer the advice given in Coding Standard 0: Don't Sweat the Small
Stuff, from "C++ Coding Standards" by Alexandrescue and Sutter.
--
"The Direct3D Graphics Pipeline" -- DirectX 9 version available for download
<http://legalizeadulthood.wordpress.com/the-direct3d-graphics-pipeline/>

Legalize Adulthood! <http://legalizeadulthood.wordpress.com>

Alf P. Steinbach

unread,
Jan 10, 2012, 1:12:10 AM1/10/12
to
On 10.01.2012 07:05, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> "Alf P. Steinbach"<alf.p.stein...@gmail.com> spake the secret code
> <jeg3u2$fen$1...@dont-email.me> thusly:
>
>> No, there is no good reason: one should in general reserve ALL UPPERCASE
>> identifiers for macros.
>>
>> But they should be used for macros.
>
> I've seen people defining constant quantities like this in upper case
> because they are used to only being able to define constants with
> macros and they've equated the semantic category of "constants" to
> "macros" in their mind.
>
> I could go either way about it.
>
> I prefer the advice given in Coding Standard 0: Don't Sweat the Small
> Stuff, from "C++ Coding Standards" by Alexandrescue and Sutter.

Well, I also like that statement, and have also quoted it many times.

However, I think "small stuff" is mainly stuff that only impacts on the
feelings of proponents of this scheme and that.

Things that have associated costs such as wasted work time, especially
for others, are IMHO not that kind of small stuff, to be disregarded.
Name collisions have such costs. Reduced readability have such costs.


Cheers,

- Alf

BCFD36

unread,
Jan 10, 2012, 1:35:17 AM1/10/12
to
I fully agree. If the original author had just added a comment about
what this was, it would have been no problem. Obscure with an
explanation I can handle. Obscure and just sitting there with everything
else, which also has no explanation, is just wrong.



--
Dave Scruggs

Gareth Owen

unread,
Jan 10, 2012, 1:58:15 AM1/10/12
to
legaliz...@mail.xmission.com (Richard) writes:

> I've seen people defining constant quantities like this in upper case

Kernighan & Richie, to name but two.

Paavo Helde

unread,
Jan 10, 2012, 2:01:38 AM1/10/12
to
BCFD36 <bcf...@cruzio.com> wrote in news:jegihu$ri7$1...@speranza.aioe.org:
The "1<<..." style is better for several reasons, most of which kick in
when you have larger values than just 0x2:

- it clearly documents this is a bit mask
- it clearly documents there is only one bit set
- it clearly documents which bit it is so one can easily avoid
collisions with other masks and see which bits are unused

The hexadecimal notation can also do all these things, but requires more
mental effort from the reader and familiarity with the hexadecimal
notation in the first place.

Cheers
Paavo


BCFD36

unread,
Jan 10, 2012, 2:11:28 AM1/10/12
to
Only two small quibbles... it was not at all clear to me what this was
supposed to indicate. Now that I know the secret handshake, it makes
more sense. And doing it in HEX is no problem at all, at least for me.
Maybe it is the dinosaur in me.


--
Dave Scruggs

Nick Keighley

unread,
Jan 10, 2012, 3:30:40 AM1/10/12
to
On Jan 10, 7:01 am, Paavo Helde <myfirstn...@osa.pri.ee> wrote:
> BCFD36 <bcf...@cruzio.com> wrote innews:jegihu$ri7$1...@speranza.aioe.org:
> > On 1/9/12 5:30 PM, Ian Collins wrote:
> >> On 01/10/12 02:11 PM, BCFD36 wrote:

[strange legacy code]

> >>> const unsigned int WAKEUP_MASK = (1<< 1) ;
>
> >>> Is there any reason for doing this, other than to make the code even
> >>> more obscure?

it's quite acommon idiom (the sift that is). I've always thought it a
bit twee. "I'm so cool I can do clever things with bit operators, even
though I don't know hex!".

Perhaps better would be

const unsigned BIT0 = 1;
const unsigned BIT1 = 2;
const unsigned BIT2 = 4;
const unsigned BIT3 = 8;
// etc.

then

const unsigned WAKEUP_MASK = BIT1;

> >> In addition to Alf's comments, the form is quite common especially in
> >> the embedded or driver world. Although it is more common to see
> >> something like
>
> >> const unsigned wakeupBit = 1;
> >> const unsigned someOtherBit = 2;
>
> >> // other bit definitions
>
> >> const uint32_t wakeupMask = (1u << wakeupBit);
>
> > Interesting. I didn't know the form is common. I've never seen it
> > before, but I don't do much driver work and haven't seen it in the
> > embedded work I have done.
>
> > Personally, I find it quite obscure and prefer the 0x0002 notation
> > myself. But I will have to think on it some more. I can see how you
> > could OR together a bunch of these and it be pretty clear which bits
> > are set. But I still find it obscure.
>
> The "1<<..." style is better for several reasons, most of which kick in
> when you have larger values than just 0x2:
>
>   - it clearly documents this is a bit mask

not really

>   - it clearly documents there is only one bit set

sort of

>   - it clearly documents which bit it is so one can easily avoid
> collisions with other masks and see which bits are unused

I submit my named constantrs are clearer

> The hexadecimal notation can also do all these things, but requires more
> mental effort from the reader and familiarity with the hexadecimal
> notation in the first place.

scarey thought. There are people writing device drivers that don't
know hex?

Alf P. Steinbach

unread,
Jan 10, 2012, 10:31:59 AM1/10/12
to
On 10.01.2012 09:30, Nick Keighley wrote:
>
> scarey thought. There are people writing device drivers that don't
> know hex?

Why not use octal? Saves you typing an "x". After all, the creators of C
were quite happy with octal for expressing low level bit patterns.


Cheers,

- Alf

Scott Lurndal

unread,
Jan 10, 2012, 12:14:26 PM1/10/12
to
Assuming you're not having us on, you can't evenly divide 8, 16, or 32 by three.

Octal made sense in the 12-bit and 36-bit worlds from which the creators of C
hailed.

scott

Victor Bazarov

unread,
Jan 10, 2012, 3:11:39 PM1/10/12
to
Are you saying that 040 is more difficult to read than 0x20? Just
checking...

V
--
I do not respond to top-posted replies, please don't ask

Richard

unread,
Jan 10, 2012, 3:45:27 PM1/10/12
to
It is.

Jorgen Grahn

unread,
Jan 10, 2012, 4:51:44 PM1/10/12
to
Perhaps both Alf and you are joking and my humor center is out of
operation, but anyway:

I learned programming 20 years ago, and never found any reason to
learn to read octal, other than in the very limited field of Unix file
protection bits. It takes practice, and very, very few people get that
practice these days.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Jorgen Grahn

unread,
Jan 10, 2012, 4:58:09 PM1/10/12
to
On Tue, 2012-01-10, Alf P. Steinbach wrote:
> On 10.01.2012 02:11, BCFD36 wrote:
>> I am working on a piece of legacy code that has many, shall we say,
>> strange things. This one, as J.K. Anderson (classics Prof at UC
>> Berkeley) used to say, "baffles me". It has the following statement in
>> the code:
>>
>> const unsigned int WAKEUP_MASK = (1<< 1) ;
...
> Also, there is no reason for the keyword `int`.

Oddly, I've recently met two decent/good programmers who didn't know that
the 'int' in 'unsigned int' is redundant. One asked me if just writing
'unsigned' was a GCC extension!

I suspect others write 'unsigned int' because they believe verbosity
increases readability. I remember I did that very early in my career.

David Dyer-Bennet

unread,
Jan 10, 2012, 5:46:22 PM1/10/12
to
I write "unsigned int" because making just "unsigned" work is a clear
mistake in the standard :-).

--
David Dyer-Bennet, dd...@dd-b.net; http://dd-b.net/
Snapshots: http://dd-b.net/dd-b/SnapshotAlbum/data/
Photos: http://dd-b.net/photography/gallery/
Dragaera: http://dragaera.info

Jens Thoms Toerring

unread,
Jan 10, 2012, 6:41:05 PM1/10/12
to
I use the "unsigned int" form I guess due to some sense of sym-
metry, since I also have to write "unsigned long" and "unsigned
short" (and I wouldn't consider 4 more characters as "verbosity"
and, yes, to me it looks a bit more readable or at least it may
stop me from from getting distracted by wondering "Did I really
mean 'int' or did I perhaps forgot about the 'long' or 'short'?"
when I later read it again).
Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

Jorgen Grahn

unread,
Jan 10, 2012, 7:19:06 PM1/10/12
to
On Tue, 2012-01-10, Jens Thoms Toerring wrote:
> Jorgen Grahn <grahn...@snipabacken.se> wrote:
>> On Tue, 2012-01-10, Alf P. Steinbach wrote:
>> > On 10.01.2012 02:11, BCFD36 wrote:
>> >> I am working on a piece of legacy code that has many, shall we say,
>> >> strange things. This one, as J.K. Anderson (classics Prof at UC
>> >> Berkeley) used to say, "baffles me". It has the following statement in
>> >> the code:
>> >>
>> >> const unsigned int WAKEUP_MASK = (1<< 1) ;
>> ...
>> > Also, there is no reason for the keyword `int`.
>
>> Oddly, I've recently met two decent/good programmers who didn't know that
>> the 'int' in 'unsigned int' is redundant. One asked me if just writing
>> 'unsigned' was a GCC extension!
>
>> I suspect others write 'unsigned int' because they believe verbosity
>> increases readability. I remember I did that very early in my career.
>
> I use the "unsigned int" form I guess due to some sense of sym-
> metry, since I also have to write "unsigned long" and "unsigned
> short" (and I wouldn't consider 4 more characters as "verbosity"

Yes, you're right. I would have cited symmetry reasons back then.

I now think of the symmetry argument as bogus though. 'long' and
'short' are not "siblings" to 'int', just shorthand for 'long int' and
'short int'.

(And now someone will come claiming he always writes 'unsigned long
int' for maximum readability.)

MikeWhy

unread,
Jan 10, 2012, 10:53:40 PM1/10/12
to
For full, well rounded symmetry, you might consider writing 'signed long
int'.

I'm still stuck on simpler matters, 'uint32_t' for example, where 'unt32_t'
would seem more symmetric with 'int32_t'.

int32_t ifoo;
unt32_t ufoo;

uint32_t xfoo; // needs a tab rather than space to keep it aligned.


hanukas

unread,
Jan 11, 2012, 2:50:49 AM1/11/12
to
On Jan 10, 10:30 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
Sure we do know hex. But we are translating System/Catapult code and
specification into C/C++ header, that is the simplest way to do it.
Let's say we have a 5 bit field at offset 20. Sure we can juggle the
masks in our heads nibble-at-time and get the right answer 99.9% of
the time. But with this approach we do it in fraction of the time and
get it right 99.999% of the time.

We don't really care what that header looks like, what we do care
about is that RB_BLOCK_CLOCK_GATE_MASK has the right value on it. We
don't think in terms of "we are too cool to get our jobs done on
time", you know? What would doing this thing ass-backwards prove? That
we know hex? You are serious, though? Scary.

hanukas

unread,
Jan 11, 2012, 3:04:54 AM1/11/12
to
On Jan 10, 10:45 pm, Richard <rgrd...@gmail.com> wrote:
> Victor Bazarov <v.baza...@comcast.invalid> writes:
> > On 1/10/2012 12:14 PM, Scott Lurndal wrote:
> >> "Alf P. Steinbach"<alf.p.steinbach+use...@gmail.com>  writes:
> >>> On 10.01.2012 09:30, Nick Keighley wrote:
>
> >>>> scarey thought. There are people writing device drivers that don't
> >>>> know hex?
>
> >>> Why not use octal? Saves you typing an "x". After all, the creators of C
> >>> were quite happy with octal for expressing low level bit patterns.
>
> >> Assuming you're not having us on, you can't evenly divide 8, 16, or 32 by three.
>
> >> Octal made sense in the 12-bit and 36-bit worlds from which the creators of C
> >> hailed.
>
> > Are you saying that 040 is more difficult to read than 0x20?  Just checking...
>
> It is.

It's a question of point of view, as usual; in my mind I see those as:

0x20 = 0010 0000
040 = 000 100 000

It's just a different # of bits grouped together, big deal. But that
doesn't change anything. The idea of (1L << N) isn't to be readable
anyway (in the context of embedded driver work) so arguing which form
is more readable is missing the point.

So what is the point? The point is painless translation of
specification into usable header in finite time. Each field has mask
and offset, these are used through everywhere else. This comes from
digital circuit logic design languages like VHDL, SystemC, Catapult.
The idea is painless interaction between those and C/C++ (C mostly).

Bill Davy

unread,
Jan 11, 2012, 3:30:25 AM1/11/12
to
"Victor Bazarov" <v.ba...@comcast.invalid> wrote in message
news:jei61r$onp$1...@dont-email.me...
O40 loks like a number, but is not.


hanukas

unread,
Jan 11, 2012, 3:15:18 AM1/11/12
to
For the record, none of the proposed approaches are used anyway.

(1 << 4) // nope
(1U << 4) // naah
(1L << 4) // uh-huh..

Here's how it's done:

(0xf << 12) // zero-based mask shifted to correct position

Or more concrete:

SOME_REGISTER_FIELD_MASK (0xff << 16)
SOME_REGISTER_FIELD_OFFSET 16
SOME_REGISTER_FIELD_SIZE 8

Usually this is not done by hand. The HLL description of logic is
translated into C header and we always get all of these; mask, offset,
size. It's up to the driver author to use the appropriate fields where
needed.

When we type these by hand, we follow the same convention for
consistency. =)

Fred Zwarts (KVI)

unread,
Jan 11, 2012, 3:40:57 AM1/11/12
to
"Bill Davy" wrote in message news:9n4vks...@mid.individual.net...
Ox20 looks like a number, but it is not. l00 looks like a number, but it is
not. What is your point?

none Yannick Tremblay

unread,
Jan 11, 2012, 5:23:42 AM1/11/12
to
>Only two small quibbles... it was not at all clear to me what this was
>supposed to indicate. Now that I know the secret handshake, it makes
>more sense. And doing it in HEX is no problem at all, at least for me.
>Maybe it is the dinosaur in me.

0x0002 or 0x0008 is rather trivial and does not cause me to stop.
However, when the bitmask becomes used for multiple things, then I
would say that the following reads trivially while a pure hex based
implementation would force me to stop and start to very carefully
count bits:

const unsigned wakeupBit = 1;
const unsigned someOtherBit = 2;
...
const unsigned superBit = 13;
...
const unsigned hyperBit = 23;
const unsigned gigaBit = 24;
...
const unsigned ultraBit = 29;

const uint32_t theMask = (1u<< wakeupBit)
& (1u<< someOtherBit)
& (1u<< superBit)
& (1u<< hyperBit)
& (1u<< gigaBit)
& (1u<< utraBit) ;

followed elsewhere by:

if( theMask & superBit ) ...


Yannick

none Yannick Tremblay

unread,
Jan 11, 2012, 5:37:48 AM1/11/12
to
In article <jejnve$ff5$1...@dont-email.me>,
Arggh!!! Obviously | not &

>const uint32_t theMask = (1u<< wakeupBit)
> | (1u<< someOtherBit)
> | (1u<< superBit)
> | (1u<< hyperBit)
> | (1u<< gigaBit)
> | (1u<< ultraBit) ;

hanukas

unread,
Jan 11, 2012, 9:50:28 AM1/11/12
to
On Jan 11, 10:40 am, "Fred Zwarts \(KVI\)" <F.Zwa...@KVI.nl> wrote:
> "Bill Davy"  wrote in messagenews:9n4vks...@mid.individual.net...
>
> >"Victor Bazarov" <v.baza...@comcast.invalid> wrote in message
> >news:jei61r$onp$1...@dont-email.me...
> >> On 1/10/2012 12:14 PM, Scott Lurndal wrote:
> >>> "Alf P. Steinbach"<alf.p.steinbach+use...@gmail.com>  writes:
> >>>> On 10.01.2012 09:30, Nick Keighley wrote:
>
> >>>>> scarey thought. There are people writing device drivers that don't
> >>>>> know hex?
>
> >>>> Why not use octal? Saves you typing an "x". After all, the creators of
> >>>> C
> >>>> were quite happy with octal for expressing low level bit patterns.
>
> >>> Assuming you're not having us on, you can't evenly divide 8, 16, or 32
> >>> by three.
>
> >>> Octal made sense in the 12-bit and 36-bit worlds from which the creators
> >>> of C
> >>> hailed.
>
> >> Are you saying that 040 is more difficult to read than 0x20?  Just
> >> checking...
>
> >> V
> >> --
> >> I do not respond to top-posted replies, please don't ask
>
> >O40 loks like a number, but is not.
>
> Ox20 looks like a number, but it is not. l00 looks like a number, but it is
> not. What is your point?

I guess he meant base-10 decimal number? The leading zero is the tip-
off for C/C++ programmers that it's octal.

Juha Nieminen

unread,
Jan 11, 2012, 10:14:32 AM1/11/12
to
Jorgen Grahn <grahn...@snipabacken.se> wrote:
> I suspect others write 'unsigned int' because they believe verbosity
> increases readability. I remember I did that very early in my career.

I have the exact opposite experience: Most noobs believe that verbosity
decreases readability, and thus proceed to write what effectively is
obfuscated C++.

Unfortunately, even some experienced professionals have this
misconception.

Victor Bazarov

unread,
Jan 11, 2012, 11:46:40 AM1/11/12
to
<shrug>

Read quickly: Raedablity is a mtater of ahbit and is'nt guiedd by eaxct
precpetpion; itis fzuzy.

You managed to read the line above, didn't you? It's the same way with
the source. 'unsigned int' or 'unsigned' doesn't really matter for
readability. A quick glance gives all the information one needs.
However, when it comes to bits and their positions, it's different. I
guess, it all comes down to the degree of complexity and one's knack to
read (comprehend) what others might consider obscure, like hexadecimals
or octals.

Here is another example. In our codebase we have tons of flags, most of
which have symbolic representation. That representation hasn't changed
in years. Yet, I can't read the value 0x29020 (only four bits, mind
you) and quickly figure out what bits are set. So, for debugging (and
only for debugging) I wrote a decoder function that displays the value
in the symbolic form... And in the code the value is never written as a
number. It's the debugging that presents a problem, AFAIC.

Scott Lurndal

unread,
Jan 11, 2012, 12:28:14 PM1/11/12
to
No, I'm saying that I can look at 0x12345678 and visually determine which
bits are set in which bytes. It's much more complicated for 02215053170.

On the other hand, when I was writing PAL-D code for the pdp8, 4 digit octal
numbers worked just fine due to the 12-bit word.

scott

Joe keane

unread,
Jan 11, 2012, 12:51:40 PM1/11/12
to
In article <jehllm$hot$1...@dont-email.me>,
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
>Why not use octal? Saves you typing an "x". After all, the creators of C
>were quite happy with octal for expressing low level bit patterns.

'we don't do that'

Virtually all computers now have eight-bit bytes. It is a common data
type, what the other data types are made of, and probably the unit of
address. It's so much nicer when the radix bits are a fraction of this.

Dump sone memory in words then interpret it in bytes, or vice versa.

David Dyer-Bennet

unread,
Jan 11, 2012, 2:28:23 PM1/11/12
to
sc...@slp53.sl.home (Scott Lurndal) writes:

> Victor Bazarov <v.ba...@comcast.invalid> writes:
>>On 1/10/2012 12:14 PM, Scott Lurndal wrote:
>>> "Alf P. Steinbach"<alf.p.stein...@gmail.com> writes:
>>>> On 10.01.2012 09:30, Nick Keighley wrote:
>>>>>
>>>>> scarey thought. There are people writing device drivers that don't
>>>>> know hex?
>>>>
>>>> Why not use octal? Saves you typing an "x". After all, the creators of C
>>>> were quite happy with octal for expressing low level bit patterns.
>>>>
>>>>
>>>
>>> Assuming you're not having us on, you can't evenly divide 8, 16, or 32 by three.
>>>
>>> Octal made sense in the 12-bit and 36-bit worlds from which the creators of C
>>> hailed.
>>
>>Are you saying that 040 is more difficult to read than 0x20? Just
>>checking...
>
> No, I'm saying that I can look at 0x12345678 and visually determine which
> bits are set in which bytes. It's much more complicated for 02215053170.

Whereas for me it's the opposite.

But wait -- what you have memorized, to decode the hex, is a superset of
what I know to decode the octal. How, then, can it be "much more
complicated" to decode the octal? It involves decoding more digits, so
I can't argue against "slightly more work" or something like that. But
the principles are identical, and the tables needed in memory are a
subset of the hex tables.

> On the other hand, when I was writing PAL-D code for the pdp8, 4 digit octal
> numbers worked just fine due to the 12-bit word.

Yep, that's where I learned to do octal. Actually toggling in the RIM
loader is where I learned to do octal.

Nick Keighley

unread,
Jan 12, 2012, 8:40:08 AM1/12/12
to
On Jan 10, 3:31 pm, "Alf P. Steinbach" <alf.p.steinbach
I've used both in the past. Hex is more compact and fits better to 8,
16 and 32 bit quantities. But i suspect you know this.

BCFD36

unread,
Jan 12, 2012, 11:42:00 PM1/12/12
to
Never try to play Blackjack when you have been working in octal for 3
years. It can mess with the math. Balancing a checkbook can get a little
dicey too.



--
Dave Scruggs

Reply all
Reply to author
Forward
0 new messages