use & or &&?

Go To Last Post
49 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everybody. Any feedback will be very much appreciated.
Let's say we want to check if two input pins are high (e.g.PC5 and PC6)and then do something. I wrote something like this:

uint8_t gpr1;
gpr1=pinc;
if (gpr1 & 0b01100000)
{//do something}

When this runs, that the program "does something" if PC5 OR PC6 is high, instead of PC5 AND PC6 being both high. Why this happens? How should I write the code to get what I really want? I would also appreciate any example on multiple/complex "if condition". e.g if (((PC5 AND PC7) ANDNOT PA4) OR PA3) ANDNOT gpr1=0xfa, do something. Thanks in advance for your feedback.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The way you have it gpr1 is anded with your variable and if EITHER bit is set it will return a non zero value.

What I think you need is

if ((gpr1 & (1<<PC6) && (gpr1 & (1<<PC5))

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Why this happens?
If statements check for true or false. Zero is considered false, any other value is considered true. (gpr1 & 0b01100000) will be non-zero if either bit is not 0 and therefore evaluate as true. You can use John's method, or you could use:

if ( (gpr1 & 0b01100000) == 0b01100000)

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

[deleted incorrect comment]

Lack of reading comprehension on my part, sorry.

Last Edited: Sun. Aug 17, 2014 - 06:36 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The (gpr1&mask1)&&(gpr1&mask2) approach reads them at least a couple of clocks apart
No it doesn't, the pins were read here:

gpr1=PINC; 

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you gentlemen! Could anyone provide an example of a complex if statement? Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I would also appreciate any example on multiple/complex "if condition". e.g if (((PC5 AND PC7) ANDNOT PA4) OR PA3) ANDNOT gpr1=0xfa, do something

Sketchy, not tested:

uint8_t pa;
uint8_t pc;

pa = PORTA;
pc = PORTC;

if (((pc & ((1<<PC5) | (1<<PC7))) && (pa & ~(1<<PA4)) || (pa & (1<<PA3))) && !(gpr1=0xfa))
{
   // Do something
}

Whether this actually does something meaningful is another question.

You need to go over to the tutorials forum and read the tutorial on "Bit manipulation".

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]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

LefterisEllhnas wrote:
I would also appreciate any example on multiple/complex "if condition".

As the old joke goes: if you have trouble with that, then just don't do it :!:

Cramming all your conditions into a single 'if' does not optimise the code - but it may well make it harder to read and harder to debug.

[/code]

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
As the old joke goes: if you have trouble with that, then just don't do it
Interesting comment.

my son is currently learning C in first year engineering. The lecturers and tutors provide sample code with quite complex conditional statements and make extensive use of assignments in while conditions.

I have suggested to my son that he unwind this stuff and take it a step at a time making sure he understands each step.

With 30 years experience I tend to write simple conditions. With GCC I find the code generated is the same so why not focus on readability.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gregd99 wrote:
Quote:
The lecturers and tutors provide sample code with quite complex conditional statements and make extensive use of assignments in while conditions ... With 30 years experience I tend to write simple conditions ... focus on readability.

I guess that's the difference between Academics & Engineers... :?:

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gregd99 wrote:
sample code with quite complex conditional statements and make extensive use of assignments in while conditions.

Reminds me of an old rant of mine about "sample code":

http://www.8052.com/forumchat/re...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I guess that's the difference between Academics & Engineers...

No.

The difference between bad Academics and good Academics/Engineers. FWIW I classsified as an "academic" fo some 10 years. I always taught

- Keep it simple
- Optimize for maintenance
- Code is read a lot more than it is written

etc..

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]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

- Code is read a lot more than it is written

Indeed!

It has been said that the purpose of source code is more for the benefit of other human readers than it is for the target CPU.

eg, http://thehardcorecoder.com/2014...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

With 30 years experience I tend to write simple conditions. With GCC I find the code generated is the same so why not focus on readability.

+1

(and these days it's not just GCC - any decent compiler will optimize well so splitting things for readability costs nothing).

Quote:

Sketchy, not tested:

Bet you'd get more mileage reading PINA and PINC ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:
With GCC I find the code generated is the same

+1

(and these days it's not just GCC - any decent compiler will optimize well so splitting things for readability costs nothing).


Indeed!

I wrote:
Cramming all your conditions into a single 'if' does not optimise the code

Or, in general, trying to cram any expression or section of code into as few source lines as possible.

In 'Getting the Least Out of Your C Compiler', Jakob Engblom, IAR Systems, wrote:
4.9 Do Not Write Clever Code
Some C programmers believe that writing fewer source code characters and making clever use of C constructions will make the code smaller or faster. The result is code which is harder to read, and which is also harder to compile. Writing things in a straightforward way helps both humans and compilers understand your code, giving you better results.

http://user.it.uu.se/~jakob/publ...

And, of course:

Brian Kernighan (of K&R fame) wrote:
Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?

http://en.wikiquote.org/wiki/Bri...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Bet you'd get more mileage reading PINA and PINC

The example request was not specific re PORTx or PINx. I just choswe one. It seemed to be more about when/how to use logic v/s bitwise operators.

I'm surprised no-one has yet bitten on my assignment within the condition. Another thing to avoid, IMO. (This too was part of the request.)

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]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Avoid "IMO"? What is this?
I also have to say that I haven't yet understood how & works and how && works... I mean, I know how AND works for two bits, and also how it works for two bytes, but I can't really get how the if statement handle this two...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"IMO" = In My Opinion

  • && is the logical AND; so each operand is considered as just a boolean value - true or false
  • & is the bit-wise AND; so each individual bit within the left-hand operand is ANDed with the corresponding single bit in the right-hand operand and the result gives a single bit in the result
Quote:
I can't really get how the if statement handle this two

The if statement simply looks at the value (result) of the expression:
  • If the value is zero, that is considered to mean 'false';

  • If the value is nonzero, that is considered to mean 'true'
if( expression )
{
   // Go here when expression is nonzero; ie 'true'
}
else
{
   // Go here when expression is zero; ie 'false'
}

So it really makes no difference to the 'if' whether expression uses & or && or anything else; it's only the value (result) that matters - not what operators were used to obtain it.

[Edited: I had '&' and '&&' transposed!]

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Aug 22, 2014 - 06:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

& is bitwise AND. For A & B, each bit of A is ANDed with the corresponding bit in B. The result is a value with the same number of bits as A and B (or rather, the largest of them). e.g.

A = 0b01010101;
B = 0b00001111;
C = A & B;
//The value of C is now 0b00000101

&& is logical AND. For C && D, both C and D are evaluated as a boolean value, then then those values are ANDed. The result is TRUE or FALSE (1 or 0). e.g.

A = 0b01010101;
B = 0b00001111;
C = A & B;
//The value of C is 1 since both A and B evaluate to true

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

& is the logical AND; so each operand is considered as just a boolean value - true or false
&& is the bit-wise AND; so each individual bit within the left-hand operand is ANDed with the corresponding single bit in the right-hand operand and the result gives a single bit in the result

The other way around, surely?

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
"IMO" = In My Opinion

Endless online glossaries are available; eg,

http://www.parashift.com/c++-faq...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IMO = In My Opinion. Johan was saying that was his opinion.

As for & versus && you first have to understand it at the level before you understand how it's implemented at an opcode level. Single & is easiest to understand if you are an Asm programmer because it's the binary operation and really does a bitwise AND. Every bit pair from each input is used as input to an AND operation where the output bit is only 1 if both input bits are. The && operation is further removed from the concept of bits as it's a "logical" operation in C. The two inputs are first considered as to whether they represent true or false where false is 0 and true is not false. Then && combines the two values only delivering true if both inputs are true. It's usual to represent false as 0 and true as 1 but in reality any non zero is true.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

LefterisEllhnas wrote:
Avoid "IMO"? What is this?
The complete sentence makes more sense.
Quote:
I also have to say that I haven't yet understood how & works and how && works... I mean, I know how AND works for two bits, and also how it works for two bytes, but I can't really get how the if statement handle this two...
fred && greg is 1, an int, iff both fred and greg are non-zero, otherwise, 0.
abcd...efgh & stuv...wxyz == (a.s)(b.t)(c.u)(d.v)...(e.w)(f.x)(g.y)(h.z)
After the usual arithmetic conversions,
operands for & have at least 16 bits, hence the "..."s.
The other dots on the rhs represent boolean and.
This is not gcc- or AVR-specific. It is standard C

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meolsen wrote:
The other way around, surely?

Ahem - Yes!

:oops:

(edited the post)

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
TRUE or FALSE (1 or 0)

Not quite: TRUE is not necessarily 1 - it is any non-zero value.
Quote:
//The value of C is 1 since both A and B evaluate to true

Again, TRUE is not necessarily 1.

This is why one should never write, say,

if( something == TRUE )

[/code]

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

This is why one should never write, say,
Code:
if( something == TRUE )

Another reason, although more of an up-nosed language-police aspect, is that it is a tautology of sorts.

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]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Again, TRUE is not necessarily 1.

Sure. But this was supposed to be (but was yet another & / && confusion in this thread) about the result of a logic expression. It will always be 0 or 1 .

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Quote:

I guess that's the difference between Academics & Engineers...

No.

The difference between bad Academics and good Academics/Engineers. FWIW I classsified as an "academic" fo some 10 years. I always taught

- Keep it simple
- Optimize for maintenance
- Code is read a lot more than it is written

etc..

I find if you optimize for size, specifically abstracting common functionality, you automatically get maintenance benefits. I see sooo much cut/paste even in what people might assume is "well maintained" code. For example look at the avrdude sources.

Another thing I haven't seen taught in universities is good code library concepts. I cringe when I see Arduino "libraries" that include instructions to change header files in the library with the pins in your schematic.

i.e. stepper.h has:
#define STEP_UP_PIN 4
#define STEP_DOWN_PIN 5

Better libraries will have these values passed as a constructor parameter, but this is a bit bloated for classes written as singletons.

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

specifically abstracting common functionality, you automatically get maintenance benefits.

Yes, redundancy is one of the primary evils that should be fought vigorously.

Quote:

Better libraries will have these values passed as a constructor parameter, but this is a bit bloated for classes written as singletons.

As long as we are talking C++, and embedded, a template class might well be an alternative. Then again, it would make the "Arduino language" (lacking a better term) more complicated, and make it less of a match for the intended audience.

If we're down at plain C, or assembler for that matter, the idea of altering things in a header/include file to match ones wire-up and/or "modifyable" is not inherently bad either, IMO. But then there should be one header file for the non-changing stuff and one for the project-specific stuff. The "library" maker supplies a template for the project-specific stuff with comments documenting how changes affects the library.

In the end the world is not black and white but different shades of grey a lot of the time. The trick is to avoid the poisonous green gooey stuff. :D

[EDIT: Speling-corecktions]

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]

Last Edited: Sat. Aug 23, 2014 - 06:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
In the end the world is not black and while but different shades of grey a lot of the time. The trick is to avoid the poisonous green gooey stuff. :D
Wunnerful. One for the signature files.
May I quote you like this:
"In the end, the world is not black and while but different shades of grey a lot of the time.
The trick is to avoid the poisonous green gooey stuff." -- Johan Ekdahl

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ralphd wrote:
Another thing I haven't seen taught in universities is good code library concepts. I cringe when I see Arduino "libraries" that include instructions to change header files in the library with the pins in your schematic.

i.e. stepper.h has:
#define STEP_UP_PIN 4
#define STEP_DOWN_PIN 5

Better libraries will have these values passed as a constructor parameter, but this is a bit bloated for classes written as singletons.

Some things should remain macros.
The way to handle stepper.h is in another header file:
#ifndef MY_STEPPER__H
#define MY_STEPPER__H 1

#include stepper.h
#undef STEP_UP_PIN
#undef STEP_DOWN_PIN
#define STEP_UP_PIN ...
#define STEP_DOWN_PIN ...

#endif

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Not quite: TRUE is not necessarily 1 - it is any non-zero value.
The result of something being evaluated as a boolean will always be 1 or 0.
Quote:
Again, TRUE is not necessarily 1.
But the value of C will be 1. The result of a boolean operation will always be 1 or 0.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

If we're down at plain C, or assembler for that matter, the idea of altering things in a header/include file to match ones wire-up and/or "modifyable" is not inherently bad either, IMO. But then there should be one header file for the non-changing stuff and one for the project-specific stuff.

That's a much better way. When everything is mixed in one header it's a nightmare to merge in updates from upstream.

I recently started experimenting with something different - including .c files. It feels a bit wierd, but I can't think of any good reason not to. And it solves configuration issues. The hd44780 library I wrote is in a file "lcd.c" that gets included in main.c. Before the include, you can define the port to be used. If you don't a default is used:

#ifndef DATA_PORT
#warning Using default of PORTD for LCD I/O
#define DATA_PORT PORTD
#define DATA_PORT_DIR DDRD

With older compilers it could have contributed to code bloat with unused functions still getting compiled in, but with -ffunction-sections or -flto that's no longer a concern.

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I recently started experimenting with something different - including .c files. It feels a bit wierd, but I can't think of any good reason not to.
As long as you ensure that it is only included in one place in your project, then it won't cause problems, but I don't see how it improves things either. Surely you could put the default defines in lcd.h and include that instead.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

. It feels a bit wierd, but I can't think of any good reason not to. And it solves configuration issues. The hd44780 library I wrote is in a file "lcd.c" that gets included in main.c.

We've been down that path more times than I can count.

- Either make sure you are including it into only one compiled .c file because otherwise the linker will protest about duplicate definitions,

- or make all functions inlined static and in this case, if you include into several compiled files you will get duplicated copies of generated code for them.

If you know what you're doing the technique presents no (or only manageable problems). You can handle this. The sad thing is the recurring influx of posts where a noob does this, for the wrong reason, with the wrong technique etc and learns a bad habit.

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]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
Quote:
I recently started experimenting with something different - including .c files. It feels a bit wierd, but I can't think of any good reason not to.
As long as you ensure that it is only included in one place in your project, then it won't cause problems, but I don't see how it improves things either. Surely you could put the default defines in lcd.h and include that instead.
That does not solve the issue of how to cause the compilation of a library's .c file.
A #include is the most convenient way.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
JohanEkdahl wrote:
In the end the world is not black and while but different shades of grey a lot of the time. The trick is to avoid the poisonous green gooey stuff. :D

Wunnerful. One for the signature files.
May I quote you [...?]

You are most welcome! Just fix the spelign mistacke.. (while -> white)

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]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
A #include is the most convenient way.

In the end the world is not black and white... :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]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
But then there should be one header file for the non-changing stuff and one for the project-specific stuff.
Most of my libraries are configurable entirely by the use of user-supplied macros. In any given project I deliver all the macros for all the libraries via one globally included file, usually called include.h.

That is, my makefiles have:

INCLUDE=include.h

... and each compilation unit is built with an avr-gcc command line which includes:

-include $(INCLUDE)

I generally write libraries fairly robustly so that if a configuration macro is omitted the library will issue an error or at least choose a sensible default. In no case does a configuration macro 'live' in the library's header file.

IME this is an easy way to both centralise the configuration for a given project and ensure that all compilation units see the same configuration.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ralphd wrote:
I recently started experimenting with something different - including .c files. It feels a bit wierd, but I can't think of any good reason not to.

It is, of course, entirely legal - and not unheard of.

Just like there's no real reason to just stick to calling all your source files ".c" and headers ".h" - other than that it is a well-established convention.

And that's where the trouble really starts:

JohanEkdahl wrote:
The sad thing is the recurring influx of posts where a noob does this, for the wrong reason, with the wrong technique etc and learns a bad habit.
:shock:

JohanEkdahl wrote:
As long as you ensure that it is only included in one place in your project, then it won't cause problems, but I don't see how it improves things either. Surely you could put the default defines in lcd.h and include that instead.
Agreed.

skeeve wrote:
That does not solve the issue of how to cause the compilation of a library's .c file.
If you need to be compiling a library from source then, surely, you just add the source to your Project?!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
The result of something being evaluated as a boolean will always be 1 or 0.

Yes, but other things (nominally) of "boolean" type may take other values; eg, an API function returning a "boolean" result.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
ralphd wrote:
I recently started experimenting with something different - including .c files. It feels a bit wierd, but I can't think of any good reason not to.

It is, of course, entirely legal - and not unheard of.

Just like there's no real reason to just stick to calling all your source files ".c" and headers ".h" - other than that it is a well-established convention.

.h files are source files, though not top-level source files.
Top-level source files get a .c suffix.
That leaves the issue of what suffix to give source files that are not top-level source files and are not header files.
I use .c , but I've considered .b and .ci .
Quote:
skeeve wrote:
That does not solve the issue of how to cause the compilation of a library's .c file.
If you need to be compiling a library from source then, surely, you just add the source to your Project?!
I'm not sure what you mean by this.
If you mean copy it, that is what I would want to avoid.
If the project is defined by a make file, I'd expect making it a dependency would not be hard.
Adding it to an IDE project might be more interesting.
I've not used many. If the library is one I've written or installed by hand,
I might vacillate about where it should be or what it should be called.
How well do IDEs handle that sort of thing?
If the library file is compiled directly as a top-level .c file,
one must use compiler options to get to get the configuration macros #define-d.
I'd recommend against a bunch of -D options.
'Twould work, but as documentation it's horrible.
gcc has an option to specify a file of options.
gcc has an option to automatically #include a file even though it is not mentioned in the top-level file.
gcc has an option, -I , to allow one to specify an include directory.
I expect that -D and -I are available on most compilers.
-D has one looking in the build system for the single point of truth.
-I is better, but requires dedicating a directory to a single file.
To me, #include-ing the library file seems tidier.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
.h files are source files, though not top-level source files

But only by convention - the point is that there is nothing in the language standard which mandates this.

Quote:
Top-level source files get a .c suffix.

Again, only by convention.

I wrote:
If you need to be compiling a library from source then, surely, you just add the source to your Project?!

Quote:
I'm not sure what you mean by this.

ie, you just treat it in exactly the same way as any of your "own" files in your project.

Quote:
If you mean copy it

Not necessarily.
If your project has access to #include it, then it must equally have access to compile it as a "top level" file.

Quote:
Adding it to an IDE project might be more interesting.

It shouldn't be.

Quote:
How well do IDEs handle that sort of thing?

If an IDE can't cope with that, then it's a pretty poor IDE - get one which can!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry - lost a bit:

skeeve wrote:
If the library file is compiled directly as a top-level .c file, one must use compiler options to get to get the configuration macros #define-d.
I'd recommend against a bunch of -D options.

I see your point there but, if the "library" is such that the user is intended to be building from source with their own code, then I'd expect it to have some kind of customer configuration header for that stuff...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi, if I understand well, the only chance to get a "false" when using &, is to get a result equal to 0, e.g.
A=0b01010101;
B=0b10101010;
C=A&B;
the value of C is 0, so the if statement would be "false".
And for &&, the only chance to get "false" is at least one of the bytes to be 0, e.g.
A=0b11110000;
B=0b00000000;
C=A&&B;
Now C is 0, so the if statement would be "false".
Am I right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Sorry - lost a bit:

skeeve wrote:
If the library file is compiled directly as a top-level .c file, one must use compiler options to get to get the configuration macros #define-d.
I'd recommend against a bunch of -D options.

I see your point there but, if the "library" is such that the user is intended to be building from source with their own code, then I'd expect it to have some kind of customer configuration header for that stuff...

For 8-bit AVR work, you either have to re-build from source, or your library has to have a shitload of pre-built .o's covering the various MCUs à la avr-libc.

I've played (unsucessfully so far) with makefile rules to rebuild files when compiler flags change. Using the traditional .h + .o for a library, I've messed things up by forgetting to do a "make clean" when I change MCUs.

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
then I'd expect it to have some kind of customer configuration header for that stuff...
Which brings us back to what he was objecting to in the first place: having to rewrite the header for every project. A less objectionable alternative:

lcd.c includes lcd.h
lcd.h has the default defines as described above.
lcd.h includes lcdconfig.h
lcdconfig.h has this:

#ifdef PROJECT_A
   //#defines for project A
#endif

#ifdef PROJECT_B
   //#defines for project B
#endif

Then you set a -D option in the project for the options you want. With this there is no need to change lcd.h, and you only add to lcdconfig.h so you don't loose the settings for previous projects.

Quote:
Yes, but other things (nominally) of "boolean" type may take other values; eg, an API function returning a "boolean" result.
Booleans are 0 or 1. If the function is returning something other than 0 or 1, then it is not returning a boolean.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
Quote:
then I'd expect it to have some kind of customer configuration header for that stuff...
Which brings us back to what he was objecting to in the first place: having to rewrite the header for every project. A less objectionable alternative:

lcd.c includes lcd.h
lcd.h has the default defines as described above.
lcd.h includes lcdconfig.h
lcdconfig.h has this:

#ifdef PROJECT_A
   //#defines for project A
#endif

#ifdef PROJECT_B
   //#defines for project B
#endif

Then you set a -D option in the project for the options you want. With this there is no need to change lcd.h, and you only add to lcdconfig.h so you don't loose the settings for previous projects.

The general idea works, but I'd do it a bit differently.
lcd.c and lcd.h would be from the library.
lcdconfig.h would be a project file.
lcd.h would not have defaults, but it would check
whether all the necessary symbols were #define-d.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
&& is logical AND. For C && D, both C and D are evaluated as a boolean value, then then those values are ANDed.

For "C && D", C is evaluated first, and if it is not false, D is evaluated.

&& gives short circuit evaluation.
& gives arithmetic evaluation.