## C Code Question

25 posts / 0 new
Author
Message

I'm checking out an example in a book I'm reading and I have a question regarding initialization.

```DDRB |= 1<<2|1<<3;//Declare as outputs
```

Quote:
|=
is an or declaration.

What I don't understand is why use:

```
1<<2|1<<3
```

Won't both of these conditions

Quote:
1<<2
and
Quote:
1<<3
always be true?

If they are always true why not simply declare DDRB using the following:

`DDRB = 1;`

Thanks for any help.

Last Edited: Fri. Oct 3, 2014 - 02:15 AM

Bit manipulation 101

And to answer you specific question:

`DDRB |= 1<<2|1<<3;`

1<<2 is 0x04 and 1<<3 is 0x08.

0x04 OR 0x08 is 0x0C

|= takes the existing contents and OR's the new value

Let's assume DDRB already held 0xF1 before this operation (bits7 to 4 and 1 are set).

`DDRB |= 0x0C;`

is therefore

`DDRB = 0xF1 | 0x0C;`

which is

`DDRB = 0xFD;`

So nowt only are bits 7 to 4 and 1 set but bits 2 and 3 are set too. That is the significance of the <<2 and <<3 in the original values.

Quote:
Won't both of these conditions
Quote:
1<<2

and
Quote:
1<<3

always be true?
You are confusing bit-wise OR ('|') with logical OR ('||'). Had the statement been written:

`1<<2 || 1<<3`

then you would have been correct.

Regards,
Steve A.

The Board helps those that help themselves.

Also, do you remember the relative precedences of your operators |, >>, and << ? I don't; therefore I put each phrase in parentheses.

`DDRB |= (1<<2) | (1<<3);//Declare as outputs `

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

You are experiencing a common problem that is a result of a structural defect in the C language. C is a low level language with high level data structures. C uses symbols in the same manner that math equations do. However that is completely different from how natural language uses symbols. This problem results in people writing source code as complex math formulas instead of sentences. C also has the problem that its symbols can be placed anywhere in the source line and usually -something- will compile. Some natural languages share this and others don't. English does, and most of the other European languages don't. You can put any word unchanged anywhere into an English sentence and it will be grammarically correct.
C allows source lines to be absurdly complex, which defeats the wholde purpose of source code. It is a defect in the language. What this line of code does is set bits 2 and 3 while leaving the other bits of the data entity unchanged.
A serious advanced programming language would allow you to write in your source code " Set bits 2 and 3 of ddrb" It would compile correctly instead of forcing you to use weird quasi -mate expressions. Source code is not a mate equation: it's a list of instruction to a machine. C forces you to write code as math expressions, which is why C sucks. As you are begging to find out.

Quote:

You can put any word unchanged anywhere into an English sentence and it will be grammatically correct.

You can put any word unchanged anywhere into an English sentence and it aardvark will be grammatically correct. :?

BTW did you have a nasty experience with a C compiler as a child? There has to be SOME reason it's almost certainly the most popular programming language on planet earth?

Quote:
You are experiencing a common problem that is a result of a structural defect in the C language. C is a low level language with high level data structures. C uses symbols in the same manner that math equations do. However that is completely different from how natural language uses symbols.
I'm not sure why you think that this is a defect in the language, or why you think that a programming language should be modeled after natural language. You would have just as hard a time convincing me that algebra is defective because it results in complex math formulas instead of natural language.
Quote:
You can put any word unchanged anywhere into an English sentence and it will be grammatically correct.
An absurd statement.

Regards,
Steve A.

The Board helps those that help themselves.

I used Turbo C on the PC in the 1990-1995 era. I was able to make a few highly interactive, useful, and focused programs. I've learned C and and have come to appreciate its strengths and beauties. But I've had nothing but bad luck and hair-wrenching frustration when using C (that is the free GCC complier) on the AVR. I suspected at first that it might be because of the insane so-called optimizer that destroys the code that you write, and instead substitutes code that it thinks that you wanted to write. Having been able to learn AVR assembler with an ICE200 in-circuit emulator, I simply don't see the need or any advantage to use C on any platform as limited as an AVR microcontroller.
For me, a most difficult aspect about C is its assumption that a binary logic condition
(TRUE and FALSE) is the same thing as a numeric value (zero and not-zero). Then so-called
advanced C users invoke this mistaken equivalence throughout their code, even in hidden ways
where the user has to have an advanced knowledge of the underlying inner structure of the C
language in order to understand what is happening. For example, sending a text string to
an output with getchar. Something like: do while c=getchar(infile) printchar(c); This
assumes that the string ends with a byte value of 00. Assumes that the function will return
the value FALSE when it processes a data unit equal to zero.

The absolute most irritating aspect about C is the way that students are taught that the
more cryptic and difficult the code is to understand, the more 'elegant' and professional it is.
This is self-defeating and crazy. The clearer a language is in its ability to communicate
complex activities, the better it is. So while you can use x|=1<<2|1<<3 to set bits 2 and 3
in variable X, it would be more advanced in cyborg-human linguistics to use "set bits 2 and 3 in X"
to do the same thing. Because it is more understandable and the user doesn't need to know the
details of the computing machine's structure.

As for as English, I should have said that English is one of the only languages in the world where
any word can be any part of speech (a noun, a verb, adjective, or adverb) unchanged in a sentence and its
meaning will depend on its position in the sentence. C is like this: almost anything will compile.
Computer languages reflect the native spoken language of the people who design them. PASCAL, developed
by native German speakers, is very structured while C, written by native English speakers, is free form.

So I remain steadfast in my conclusion that C sucks.

Simonetta wrote:
...The absolute most irritating aspect about C is the way that students are taught that the more cryptic and difficult the code is to understand, the more 'elegant' and professional it is...

That is total nonsense.

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Keep in mind the OP question seems to
spawn from his reading of a book.
So, that may explain his assumptions and questions. The OP might not even have access
to programming tools and perhaps hardware to test.

from OP:

Quote:
I'm checking out an example in a book I'm reading and I have a question regarding initialization.

Also, I just don't think C sucks :roll:
It has been around for a long time and from what I can tell, it is still the most popular language for embedded control projects based on micro's (?).

I'll believe corporations
are people when Texas executes one.

All the 'procedural' languages like c fortran pascal and basic are about the same. They all have an if then else, a loop that tests at the top, a loop that tests at the bottom, about the same math and logic operators (but maybe different symbols). The syntax of setting and resetting bits in a byte in a register by using the shift operator is SUPPOSED to make program maintenance easier by expressing the bit names that are set and reset rather than their 'bit mask'. If you want to set bit 3 from the right in the uart register, you sort of know that that is the same as ORing whats in the port with 8, which is 1 << 3, and if bit 3 (c dudes always start counting at 0) is the UART READY bit, that is readable and understandable by the carbon based units. But it is also 3 levels deep in abstraction. PORTX = 0x69 is very understandable if you have the data sheet open in front of you and can look up every bit. 6 months from now you will forget what the bits in each position do, and might start liking the 1 << 3 notation.

Imagecraft compiler user

Quote:
C is like this: almost anything will compile.
Also an absurd statement. Case in point:
Quote:
Something like: do while c=getchar(infile) printchar(c);
That line of code has absolutely no chance of compiling.
Quote:
For me, a most difficult aspect about C is its assumption that a binary logic condition (TRUE and FALSE) is the same thing as a numeric value (zero and not-zero).
This statement is false. TRUE is always 1 and FALSE is always 0. What you are referring to is the opposite: when an integer used in a boolean statement, a non-zero value is interpreted as TRUE.
Quote:
Having been able to learn AVR assembler with an ICE200 in-circuit emulator, I simply don't see the need or any advantage to use C on any platform as limited as an AVR microcontroller.
Your original argument was that C was not easy to read or understand, yet surely C is far more readable and understandable that assembly. You also argue that C doesn't divorce you from the internal structure of the machine, yet surely assembly is directly and inexorably tied to that structure.

But above all, you have failed to show anything to support your original statement that C is somehow "defective".

Regards,
Steve A.

The Board helps those that help themselves.

Anyway, back on topic. mr805newbie - you're already showing a great ability to question *why* things work and why we do them rather than just copy-paste learning, which is absolutely commendable. Keep that up, don't ever be satisfied until you understand how it all works.

In your specific case, the C language has two types of "OR" operator, one that operates on all the bits and produces a single bit output if any of the bits in either expression are 1:

```0b00000000 || 0b000000001 (result TRUE)
0b00000001 || 0b000000001 (result TRUE)
0b11111000 || 0b100000001 (result TRUE)
0b00000000 || 0b000000000 (result FALSE)
```

This is called the "logic" OR operator, and is used to produce standard true/false boolean logic. There's also a second OR operator called the "bitwise" OR, which performs a logical OR on each bit of the two elements in the expression:

```0b00000000 | 0b00000001 (result 0b00000001)
0b00000001 | 0b00000001 (result 0b00000001)
0b10001111 | 0b10000001 (result 0b10001111)```

This is the version used in the code sample you are confused about - the code is bitwise ORing the individual bits to get a final mask, and not just checking if any of the bits in the expression are set.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

Thank you everyone. I truly appreciate the information and opinions.

I also found this which supports what is being explained here.

http://youtu.be/d0AwjSpNXR0

I'm sure this won't be the last time I post, but thank you for the great community support.

Quote:

There has to be SOME reason it's almost certainly the most popular programming language on planet earth?

Hmmmm-->>Now<< we have something meaningless to debate this fine weekend.

First, the metrics as in the pointless debates over the most popular/most used AVR C compiler brand:

-- Most lines of code? Or number of programmers?
-- Most applications? Or most programmed CPUs?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Quote:

-- Most lines of code? Or number of programmers?
-- Most applications? Or most programmed CPUs?

(caveat: I said "almost certainly" ;-))

I'm going with all four. Now how does one find evidence to back this?

(oh an do I include C++ under the "C" umbrella - I'll keep that in reserve if the other figures look borderline ;-))

Quote:

oh an do I include C++ under the "C" umbrella

Doh!

What's next? Java under the Smalltalk umbrella? COBOL under Fortran? :wink:

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Is it safe to word this functionality like so?

Quote:

In order to "always" initiate a byte with the same value, for example "1" (independent of memory, flash state, brown outs and blackouts) the following method is used. This will guarantee the "OR" from the following initialization:

```DDRB |= 1<<2|1<<3;
```

IS ALWAYS:

```0x04 OR 0x08 is 0x0C
```

```0000 0001 */shift LEFT two places

0000 0100 */shifted left two places

0000 0001 */shift LEFT 3 places

0000 1000 */shifted left 3 places

0000 0100 */shifted left two places
0000 1000 */shifted left three places

0000 1100 */OR'd together is decmal-10, hex- C

*/hence, DDRB = 0x0C
*/can also be written DDRB= 0000 1100 *// can it ???
```

Quote:

Is it safe to word this functionality like so?

No, because you are not >>setting<< the register to a value. Rather, you are ORing in two bits.

For some reason, many posters on this site have a love affair with |=. There must be a sale on "|" in full-reel quantities.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Quote:
There must be a sale on "|" in full-reel quantities.

I searched both DigiKey and Mouse, but neither had them..

(Sorry - it was irresistible..)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Quote:

(Sorry - it was irresistible..)

Thank you. The old bit-pusher (aka Surly Curmudgeon) thought it was a clever mixed-metaphor. :twisted:

Even a wider part search gives no hits:
http://www.findchips.com/avail?p...|
http://octopart.com/partsearch#s...|
Those operators must be made of unobtanium.

I don't know what "independent of memory" means, but for an advanced topic OP could really be confused if the target I/O register is TIFRn. (Hint: the results can be different depending on the original contents, and = and |= may not give the same results.)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Seeing how your program is stored in flash, there is no way to guarantee anything independent of flash state.

Sid

Life... is a state of mind

Gotcha, Next step: Take a look at how the compiler converts this into assembly.

OK, religion aside - why don't people just write

```DDRB = 0x0C;

DDRB |= 1<<2|1<<3;```

I'm missing something